package cn.com.ejiakanghu.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.com.ejiakanghu.annotation.LoginUser;
import cn.com.ejiakanghu.constant.ReturnGoodsResonListConstant;
import cn.com.ejiakanghu.core.config.DirectExchangeRabbitMQConfig;
import cn.com.ejiakanghu.core.config.WechatConstant;
import cn.com.ejiakanghu.core.enums.ResultCode;
import cn.com.ejiakanghu.core.exception.CheckException;
import cn.com.ejiakanghu.core.exceptions.BizException;
import cn.com.ejiakanghu.core.rabbitmq.DirectExchangeProducer;
import cn.com.ejiakanghu.core.utils.RespUtil;
import cn.com.ejiakanghu.core.vo.BaseResult;
import cn.com.ejiakanghu.dto.*;
import cn.com.ejiakanghu.dto.extractInfo.*;
import cn.com.ejiakanghu.form.*;
import cn.com.ejiakanghu.task.OrderUnconfirmTask;
import cn.com.ejiakanghu.task.OrderUnpaidTask;
import cn.com.ejiakanghu.task.ThreadPoolPaySuccess;
import cn.com.ejiakanghu.tools.GoodsPayStyleEnum;
import cn.com.ejiakanghu.tools.OrderFeeExtNameEnum;
import cn.com.ejiakanghu.vo.*;
import cn.ejiakanghu.logistics.service.impl.LogisticBusiBaseServiceImpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.payscore.WxPayScoreResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.linlinjava.litemall.core.inventory.InventoryService;
import org.linlinjava.litemall.core.lock_rfid.LockGoodsVo;
import org.linlinjava.litemall.core.lock_rfid.LockRfidUtil;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.task.TaskService;
import org.linlinjava.litemall.core.tool.wxpayscore.WxPayScoreTool;
import org.linlinjava.litemall.core.util.InventoryUtil;
import org.linlinjava.litemall.db.config.CenterServerAddress;
import org.linlinjava.litemall.db.config.ServerAddress;
import org.linlinjava.litemall.db.dao.*;
import org.linlinjava.litemall.db.dao.app.AppHospitalMapper;
import org.linlinjava.litemall.db.dao.app.AppOrderMapper;
import org.linlinjava.litemall.db.dao.divided.AgedmallUserCustomTemplateMapper;
import org.linlinjava.litemall.db.dao.order_manage.AgedmallServiceOrderManageMapper;
import org.linlinjava.litemall.db.domain.AgedmallGoodsOnlineService;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.UserAddressInfo;
import org.linlinjava.litemall.db.jsonfield.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.*;
import org.linlinjava.litemall.db.vo.app.*;
import org.linlinjava.litemall.db.vo.logistics.LogisticsBackUserAddressData;
import org.linlinjava.litemall.db.vo.logistics.LogisticsCommonData;
import org.linlinjava.litemall.db.vo.order_manage.AgedmallPromoteAgentInfo;
import org.linlinjava.litemall.db.vo.shop.ChainLockPickup;
import org.linlinjava.litemall.db.vo.shop.HospitalSendTimePeriodDto;
import org.linlinjava.litemall.db.vo.shop.MedicalLockPickup;
import org.linlinjava.litemall.db.vo.store.CloudExpressModelForm;
import org.linlinjava.litemall.db.vo.wechat.GetTextContent;
import org.linlinjava.litemall.db.vo.wechat.ReceivedBean;
import org.linlinjava.litemall.db.vo.wechat.ToLitemallBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.com.ejiakanghu.core.enums.ResultCode.ORDER_PACKAGE_NO_AUTH;
import static org.linlinjava.litemall.db.config.WxPayScoreConfig.WX_PAY_SCORE_STATE_DONE;

@Service
public class OrderManager {
    private Logger logger = LoggerFactory.getLogger(OrderManager.class);

    @Value("${litemall.filePath}")
    private String FILEPATH;
    @Value("${litemall.fileUrl}")
    private String FILEURL;

    @Autowired
    private LitemallOrderService litemallOrderService;
    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    @Autowired
    private GoodsManager goodsManager;
    @Autowired
    private LitemallGoodsService litemallGoodsService;
    @Autowired
    private AgedmallStoreService agedmallStoreService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private LitemallGoodsProductService productService;
    @Autowired
    private LitemallAftersaleService litemallAftersaleService;
    @Autowired
    private AgedmallGoodsShipTypeService agedmallGoodsShipTypeService;
    @Autowired
    private AgedmallReturnGoodsRecordService agedmallReturnGoodsRecordService;
    @Autowired
    private AgedmallReplenishNoticeService agedmallReplenishNoticeService;
    @Autowired
    private AgedmallLeaseGoodsReturnRecordService agedmallLeaseGoodsReturnRecordService;
    @Autowired
    private AgedmallOrderSerialService agedmallOrderSerialService;
    @Autowired
    private AgedmallGoodsServiceService agedmallGoodsServiceService;
    @Autowired
    private LitemallAddressService litemallAddressService;
    @Autowired
    private LitemallCartService litemallCartService;
    @Autowired
    private AgedmallLeaseSubbackConfService agedmallLeaseSubbackConfService;
    @Autowired
    private LitemallGoodsSpecificationService litemallGoodsSpecificationService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WxPayScoreTool wxPayScoreTool;
    @Autowired
    private WxMaService wxService;
    @Autowired
    private AgedmallShipChargeRuleService agedmallShipChargeRuleService;
    @Autowired
    private AgedmallGoodsSaleInfoService agedmallGoodsSaleInfoService;
    @Autowired
    private AgedmallDeductDetailService agedmallDeductDetailService;
    @Autowired
    private AgedmallOrderLogisticsService agedmallOrderLogisticsService;
    @Autowired
    private AgedmallStoreGoodsService agedmallStoreGoodsService;
    @Autowired
    private AgedmallExplainService agedmallExplainService;
    @Autowired
    private AgedmallFreightTemplateService agedmallFreightTemplateService;
    @Autowired
    private InventoryUtil inventoryUtil;
    @Resource
    private AgedmallCloudHouseService agedmallCloudHouseService;
    @Autowired
    private PackageService packageService;
    @Autowired
    private LockRfidUtil lockRfidUtil;
    @Resource
    private AppOrderMapper appOrderMapper;
    @Resource
    private AgedmallDeliveryManInfoMapper agedmallDeliveryManInfoMapper;
    @Resource
    private LogisticBusiBaseServiceImpl logisticBusiBaseServiceImpl;
    @Resource
    private LitemallOrderGoodsMapper litemallOrderGoodsMapper;
    @Resource
    private AgedmallStoreMapper agedmallStoreMapper;
    @Resource
    private AgedmallCloudHouseMapper agedmallCloudHouseMapper;
    @Resource
    private LitemallUserMapper litemallUserMapper;
    @Resource
    private AgedmallLgBusiRecordMapper agedmallLgBusiRecordMapper;
    @Resource
    private AgedmallLgBusiImgMapper agedmallLgBusiImgMapper;
    @Resource
    private AgedmallLgMissionMapper agedmallLgMissionMapper;
    @Resource
    private AgedmallServiceOrderMapper agedmallServiceOrderMapper;
    @Autowired
    private LitemallGoodsProductService litemallGoodsProductService;
    @Resource
    private AgedmallOnlineCityMapper agedmallOnlineCityMapper;
    @Resource
    private AgedmallLgBaseInfoMapper agedmallLgBaseInfoMapper;
    @Resource
    private AgedmallLgThirdLogisRecordMapper agedmallLgThirdLogisRecordMapper;
    @Resource
    private OrderCalcService orderCalcService;
    @Resource
    private AgedmallGoodsOnlineServiceMapper agedmallGoodsOnlineServiceMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private LeaseOrderService leaseOrderService;
    @Autowired
    private AgedmallGoodsPartsService agedmallGoodsPartsService;
    @Autowired
    private AgedmallWxNoDepositService agedmallWxNoDepositService;
    @Resource
    private DirectExchangeProducer directExchangeProducer;
    @Autowired
    private AgedmallChargeTemplateService agedmallChargeTemplateService;
    @Autowired
    private AgedmallHospitalSendService agedmallHospitalSendService;
    @Autowired
    private AgedmallGoodsDeductionConfService agedmallGoodsDeductionConfService;
    @Autowired
    private AgedmallGoodsSpecificationInfoService agedmallGoodsSpecificationInfoService;
    @Resource
    private AgedmallHospitalSendGoodsAttributeMapper agedmallHospitalSendGoodsAttributeMapper;
    @Resource
    private AgedmallHospitalSendStoreAttributeMapper agedmallHospitalSendStoreAttributeMapper;
    @Autowired
    private WxPayConfig wxPayConfig;
    @Resource
    private LitemallOrderItemMapper litemallOrderItemMapper;
    @Resource
    private InventoryService inventoryService;
    @Resource
    private ServerAddress serverAddress;
    @Resource
    private AgedmallGoodsEquMapper agedmallGoodsEquMapper;

    @Resource
    private AgedmallStoreGoodsMapper agedmallStoreGoodsMapper;

    @Resource
    private AgedmallPromoteSettlementMapper agedmallPromoteSettlementMapper;

    @Resource
    private LitemallCartMapper litemallCartMapper;

    @Resource
    private LitemallRegionMapper litemallRegionMapper;

    @Resource
    private AgedmallServiceOrderManageMapper agedmallServiceOrderManageMapper;

    @Resource
    private AgedmallUserCustomTemplateMapper agedmallUserCustomTemplateMapper;

    @Resource
    private AgedmallHospitalSendSelfLocationMapper agedmallHospitalSendSelfLocationMapper;

    @Resource
    private AppHospitalMapper appHospitalMapper;
    @Resource
    private CartManager cartManager;

    @Resource
    private LitemallGoodsProductMapper litemallGoodsProductMapper;

    @Resource
    private EnvironmentConstant environmentConstant;

    @Resource
    private OrderService orderService;

    // 获取门店下配送方式
    public Map<String, Object> getExtends(List<StoreGoodsVo> storeGoodsVos, LitemallAddress litemallAddress, AgedmallHospitalSend hospitalSend,
                                          Integer channel, String hosLinkCode, List<StoreGoodsProductVo> storeGoodsProductVoList) {
        Map<String, Object> map = new HashMap<>();
        if (CollectionUtils.isEmpty(storeGoodsVos)) {
            return map;
        }
        AgedmallStore store = agedmallStoreService.findStoreById(storeGoodsVos.get(0).getStoreId());
//        AgedmallBusinessInfo businessInfo = agedmallBusinessInfoService.findByBusId(store.getBusiId());
        Map<String, Object> deliveryServiceMap = new HashMap<>();

        FeightFeeResult feightFeeResult = orderCalcService.calFeightFee(storeGoodsVos, litemallAddress, store);
        BigDecimal price = feightFeeResult.getNormalFee();
        // 是否包含云仓
        boolean flag = feightFeeResult.isContainIsCloudStore();
        if (feightFeeResult.getOutRangeRst() != null) {
            map.put("isOutRange", 1);
        }
        JSONObject normal = new JSONObject();
        normal.put("price", price);
        // 预计送达时间
        JSONObject sendTimeJson = sendTime(storeGoodsVos, store);
        normal.put("date", "最快次日达");
        normal.put("stime", sendTimeJson.getString("stime"));
        normal.put("etime", sendTimeJson.getString("etime"));

        FreightForecastDeliveryDto normalDto = goodsManager.assambleDeliveryDto("normal", normal, storeGoodsVos,
                litemallAddress, store, storeGoodsProductVoList, false, false);

        normal.put("freightDetail", normalDto.getFreightDetail());
        if (2 != store.getSupportSelfDelivery()) {
            deliveryServiceMap.put("normal", normal);
        }
        // 不包含云仓 可以自提加急预约
        if (!flag) {
            // 支持自提
            if (null != store.getSupportSelfDelivery() && (1 == store.getSupportSelfDelivery() || 2 == store.getSupportSelfDelivery())) {
                JSONObject self = new JSONObject();
                self.put("price", 0);
                self.put("desc", DeliveryDesc.SELF);
                List<StoreInfoVo> storeInfoVos = new ArrayList<>();
                StoreInfoVo storeInfoVo = StoreInfoVo.getInstance(store);
                // sunj todo 售卖有多个商品，门店改显示哪个库存？
                storeInfoVo.setStock(0);
                storeInfoVos.add(storeInfoVo);
                self.put("shopList", storeInfoVos);
                deliveryServiceMap.put("self", self);
            }
            // 单个商品支持加急预约
            if (1 == storeGoodsVos.size()) {
                StoreGoodsVo storeGoods = storeGoodsVos.get(0);

                if ((byte) 1 == storeGoods.getLogisticsType()) {
                    AgedmallFreightTemplate freightTemplate = null;
                    //物流
                    Integer sameCitySendType = storeGoods.getSameCitySendType();
                    if (sameCitySendType != null && sameCitySendType == 0) {
                        Integer express = storeGoods.getExpress();
                        freightTemplate = express != null ? agedmallFreightTemplateService.findById(express.longValue()) : null;
                    }
                    //自营
                    else {
                        Integer sameCity = storeGoods.getSameCity();
                        freightTemplate = sameCity != null ? agedmallFreightTemplateService.findById(sameCity.longValue()) : null;
                    }
                    // 支持加急
                    if (freightTemplate != null && null != freightTemplate.getCanUrgent() && 1 == freightTemplate.getCanUrgent() && 2 != store.getSupportSelfDelivery()) {
                        // 比较营业时间 还支不支持加急
                        int hour = freightTemplate.getEarlyUrgentPay() + freightTemplate.getLastUrgentPay();
                        String busTime = store.getBusinessTime();
                        String endTime = busTime.split("-")[1];
                        LocalTime time = LocalTime.parse(endTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
                        LocalTime now = LocalTime.now();
                        now = now.plusHours(hour);
                        if (now.isBefore(time)) {
                            JSONObject urgent = new JSONObject();
                            urgent.put("desc", DeliveryDesc.URGENT);
                            urgent.put("hour", hour);
                            String urgentPay = freightTemplate.getUrgentPay();
                            String[] urgentPayArr = urgentPay.split(",");
                            JSONArray monkeyList = new JSONArray();
                                JSONObject monkey = new JSONObject();
                                monkey.put("money", Double.parseDouble(urgentPayArr[0]));
                                monkeyList.add(monkey);

                            urgent.put("moneyList", monkeyList);
                            deliveryServiceMap.put("urgent", urgent);
                        }
                    }
                    // 支持预约
                    if (freightTemplate != null && null != freightTemplate.getCanAppointment() && 1 == freightTemplate.getCanAppointment() && 2 != store.getSupportSelfDelivery()) {
                        JSONObject subscribe = new JSONObject();
                        subscribe.put("desc", DeliveryDesc.APPOINTMENT);
                        // 预约都是从第二天开始 所以提前预约时间没意义 给个1小时
                        subscribe.put("aheadHour", 1);

                        JSONArray times = new JSONArray();
                        String timesJson = freightTemplate.getCanAppointmentTime();
                        JSONArray jsonArray = JSONArray.parseArray(timesJson);
                        for (Object o : jsonArray) {
                            JSONObject object = (JSONObject) o;
                            JSONObject time = new JSONObject();
                            time.put("id", object.get("id"));
                            time.put("price", object.get("extraCharge"));
                            time.put("stime", object.get("startTime"));
                            time.put("etime", object.get("entTime"));
                            times.add(time);
                        }
                        JSONArray subList = new JSONArray();
                        int day = freightTemplate.getCanAppointmentType();
                        for (int i = 1; i <= day; i++) {
                            JSONObject sub = new JSONObject();
                            LocalDate now = LocalDate.now();
                            now = now.plusDays(i);
                            sub.put("date", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                            sub.put("times", times);
                            subList.add(sub);
                        }
                        subscribe.put("subList", subList);
                        deliveryServiceMap.put("subscribe", subscribe);
                    }
                }
            }
        }

        if (null != hospitalSend && 2 != store.getSupportSelfDelivery()) {
            // 有医院小时达 都是租赁 只有一个商品
            StoreGoodsVo storeGoods = storeGoodsVos.get(0);
            deliveryServiceMap.put("hospital", assambleDeliveryMode(hospitalSend, channel, storeGoods));
        }


        map.put("deliveryService", deliveryServiceMap);
        return map;
    }


    public OrderHospitalDeliveryMode assambleDeliveryMode(AgedmallHospitalSend hospitalSend, Integer channel, StoreGoodsVo storeGoodsVo) {
        OrderHospitalDeliveryMode deliveryMode;
        AgedmallHospitalSendGoodsAttributeExample goodsAttributeExample = new AgedmallHospitalSendGoodsAttributeExample();
        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(storeGoodsVo.getId().longValue()).andHospitalSendIdEqualTo(hospitalSend.getId().longValue());
        AgedmallHospitalSendGoodsAttribute goodsAttribute = agedmallHospitalSendGoodsAttributeMapper.selectOneByExample(goodsAttributeExample);
        AgedmallHospitalSendStoreAttributeExample storeAttributeExample = new AgedmallHospitalSendStoreAttributeExample();
        storeAttributeExample.createCriteria().andStoreIdEqualTo(storeGoodsVo.getStoreId().longValue()).andHospitalSendIdEqualTo(hospitalSend.getId().longValue());
        AgedmallHospitalSendStoreAttribute storeAttribute = agedmallHospitalSendStoreAttributeMapper.selectOneByExample(storeAttributeExample);
        String[] carerSendSplit = goodsAttribute.getCarerSendType().split(",");
        switch (channel) {
            case 0:
            case 2:
            case 3:
                deliveryMode = assambleDeliveryData(0, carerSendSplit, hospitalSend, 0);
                break;
            case 1:
                //如果门店也支持到桩自提
                if ("1".equals(storeAttribute.getSendType())) {
                    deliveryMode = assambleDeliveryData(1, carerSendSplit, hospitalSend, 1);
                } else {
                    deliveryMode = assambleDeliveryData(0, carerSendSplit, hospitalSend, 0);
                }
                break;
            default:
                deliveryMode = new OrderHospitalDeliveryMode();
                break;
        }
        //只有租赁支持送货到桩
        if (storeGoodsVo.getGoodsType().equals("sale")) {
            deliveryMode.setSubHospitalSelf(null);
        }
        return deliveryMode;
    }

    /**
     * 是否医院 0- 否 1-是
     *
     * @param isHospital
     * @return
     */
    public OrderHospitalDeliveryMode assambleDeliveryData(Integer isHospital, String[] sendTypeList, AgedmallHospitalSend hospitalSend, Integer storeHospitalSelf) {
        OrderHospitalDeliveryMode deliveryMode = new OrderHospitalDeliveryMode();

        for (int i = 0; i < sendTypeList.length; i++) {
            OrderHospitalDeliveryData deliveryData = new OrderHospitalDeliveryData();
            String sendType = sendTypeList[i];
            if (isHospital == 0) {
                switch (sendType) {
                    case "0":
                        deliveryData.setName("今日小时达");
                        deliveryData.setPrice(hospitalSend.getUrgentCost());
                        deliveryData.setHour(hospitalSend.getDeliveryTime());
                        deliveryData.setDesc(DeliveryDesc.HOSPITAL_HOUR);
                        deliveryMode.setDayHourReach(deliveryData);
                        break;
                    case "1":
                        deliveryData.setName("预约门店自提");
                        deliveryData.setDay(hospitalSend.getSubscribeDay());
                        deliveryData.setAheadHour(hospitalSend.getDeliveryTime());
                        deliveryData.setSubList(assambleTimes(hospitalSend.getTimePeriod(), hospitalSend.getSubscribeDay()));
                        deliveryData.setDesc(DeliveryDesc.HOSPITAL_APPOINTMENT_STORE_SELF);
                        deliveryMode.setSubStoreSelf(deliveryData);
                        break;
                    case "2":
                        deliveryData.setName("今日门店自提");
                        deliveryData.setPrice(BigDecimal.ZERO);
                        deliveryData.setDesc(DeliveryDesc.HOSPITAL_STORE_SELF);
                        deliveryMode.setDayStoreSelf(deliveryData);
                        break;
                    case "3":
                        deliveryData.setName("预约小时达");
                        deliveryData.setDay(hospitalSend.getSubscribeDay());
                        deliveryData.setAheadHour(hospitalSend.getDeliveryTime());
                        deliveryData.setSubList(assambleTimes(hospitalSend.getTimePeriod(), hospitalSend.getSubscribeDay()));
                        deliveryData.setDesc(DeliveryDesc.HOSPITAL_APPOINTMENT_HOUR);
                        deliveryMode.setSubHourReach(deliveryData);
                        break;
                }
            } else {
                switch (sendType) {
                    case "0":
                        deliveryData.setName("今日小时达");
                        deliveryData.setPrice(hospitalSend.getUrgentCost());
                        deliveryData.setHour(hospitalSend.getDeliveryTime());
                        deliveryData.setDesc(DeliveryDesc.HOSPITAL_HOUR);
                        deliveryMode.setDayHourReach(deliveryData);
                        break;
                    case "1":
                        if (storeHospitalSelf == 1) {
                            deliveryData.setName("预约到院自提");
                            deliveryData.setDay(hospitalSend.getSubscribeDay());
                            deliveryData.setAheadHour(hospitalSend.getDeliveryTime());
                            deliveryData.setSubList(assambleTimes(hospitalSend.getTimePeriod(), hospitalSend.getSubscribeDay()));
                            deliveryData.setDesc(DeliveryDesc.HOSPITAL_HP_SELF);
                            //增加自提点
                            deliveryData.setPositionList(assambleSelfLocationData(hospitalSend.getId().longValue()));
                            deliveryMode.setSubHospitalSelf(deliveryData);
                        }
                        break;
                }
            }
        }

        return deliveryMode;
    }

    /**
     * 组装时间段
     */
    public List<OrderHospitalDeliverySub> assambleTimes(String timeString, Integer subDay) {
        List<OrderHospitalDeliverySub> deliverySubList = new ArrayList<>();
        List<HospitalSendTimePeriodDto> sendDtoList = JSON.parseArray(timeString, HospitalSendTimePeriodDto.class);
        List<OrderHospitalDeliveryTime> deliveryTimeList = new ArrayList<>();
        for (int i = 0; i < sendDtoList.size(); i++) {
            HospitalSendTimePeriodDto periodDto = sendDtoList.get(i);
            OrderHospitalDeliveryTime deliveryTime = new OrderHospitalDeliveryTime();
            deliveryTime.setId(periodDto.getId());
            deliveryTime.setStime(null != periodDto.getStartTime() ? periodDto.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm")) : null);
            deliveryTime.setEtime(null != periodDto.getEndTime() ? periodDto.getEndTime().format(DateTimeFormatter.ofPattern("HH:mm")) : null);
            deliveryTime.setPrice(periodDto.getCost());
            deliveryTimeList.add(deliveryTime);
        }
        for (int i = 1; i <= subDay; i++) {
            OrderHospitalDeliverySub sub = new OrderHospitalDeliverySub();
            LocalDate now = LocalDate.now();
            now = now.plusDays(i);
            sub.setDate(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            sub.setTimes(deliveryTimeList);
            deliverySubList.add(sub);
        }
        return deliverySubList;
    }

    /**
     * 组装自提点
     */
    public List<OrderHospitalDeliverySelfLocationData> assambleSelfLocationData(Long hospitalId){
        List<OrderHospitalDeliverySelfLocationData> locationData;
        AgedmallHospitalSendSelfLocationExample locationExample=new AgedmallHospitalSendSelfLocationExample();
        locationExample.createCriteria().andHospitalIdEqualTo(hospitalId).andDeletedEqualTo(false);
        List<AgedmallHospitalSendSelfLocation> selfLocationList = agedmallHospitalSendSelfLocationMapper.selectByExample(locationExample);
        locationData=OrderHospitalDeliverySelfLocationData.transfToLocationData(selfLocationList);
        return locationData;
    }


    private JSONObject sendTime(List<StoreGoodsVo> storeGoodsVos, AgedmallStore store) {
        Integer beginTime = 24;
        Integer endTime = 48;
        for (StoreGoodsVo goodsVo : storeGoodsVos) {
            // 云仓没有预计时间  暂时先删除
//            if (InventoryUtil.STOCK_CLOUD.equals(goodsVo.getStockType())) {
//                continue;
//            }
            Integer tempBeginTime = null;
            Integer tempEndTime = null;
            // 统计费用直接取，模板费用取模板配置
            if ((byte) 0 == goodsVo.getLogisticsType()) {
                tempBeginTime = goodsVo.getSendFastestTime();
                tempEndTime = goodsVo.getSendSlowestTime();
            } else {
                Long templateId=null;
                if (goodsVo.getSameCitySendType() == 0) {
                    templateId=goodsVo.getExpress().longValue();
                } else {
                    templateId = goodsVo.getSameCity().longValue();
                }
                AgedmallFreightTemplate freightTemplate = agedmallFreightTemplateService.findById(templateId);
                if (freightTemplate != null) {
                    tempBeginTime = freightTemplate.getSendFastestTime();
                    tempEndTime = freightTemplate.getSendSlowestTime();
                }
            }

            if (null != tempBeginTime) {
                if (null == beginTime || tempBeginTime < beginTime) {
                    beginTime = tempBeginTime;
                }
            }
            if (null != tempEndTime) {
                if (null == endTime || tempEndTime > endTime) {
                    endTime = tempEndTime;
                }
            }
        }

        JSONObject object = new JSONObject();
        if (null != beginTime && null != endTime) {
            String busTime = store.getBusinessTime();
            String busEndTime = busTime.split("-")[1];
            LocalTime time = LocalTime.parse(busEndTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
            LocalTime now = LocalTime.now();
            now = now.plusHours(endTime);
            if (now.isBefore(time)) {
                object.put("date", LocalDate.now().format(DateTimeFormatter.ofPattern("MM-dd")));
            } else {
                object.put("date", LocalDate.now().plusDays(1).format(DateTimeFormatter.ofPattern("MM-dd")));
            }
            object.put("stime", LocalTime.now().plusHours(beginTime).format(DateTimeFormatter.ofPattern("HH:mm:ss")));
            object.put("etime", LocalTime.now().plusHours(endTime).format(DateTimeFormatter.ofPattern("HH:mm:ss")));
        }
        return object;
    }

    // 是否超出配送范围
    public boolean isDelivery(StoreGoodsVo storeGoodsVo, LitemallAddress litemallAddress, boolean isCloudStock, Integer cloudId) {
        // 云仓 没配模板，没有超范围一说。配模板，查看模板范围
        if (isCloudStock) {
            return CloudIsDelivery(storeGoodsVo, litemallAddress, cloudId);
            // 同城配送，有模板 查模板违反。没模板，看门店范围
        } else {
            return SameCityIsDelivery(storeGoodsVo, litemallAddress);
        }

    }

    /**
     * 云仓配送是否超出范围
     *
     * @return
     */
    public boolean CloudIsDelivery(StoreGoodsVo storeGoodsVo, LitemallAddress litemallAddress, Integer cloudId) {
        if ((byte) 1 == storeGoodsVo.getLogisticsType()) {
            List<CloudExpressModelForm> cloudExpressModelFormList = JSONArray.parseArray(storeGoodsVo.getCloudJson(), CloudExpressModelForm.class);
            CloudExpressModelForm beChooseCloud = cloudExpressModelFormList.stream().filter(cloudExpress -> cloudExpress.getId().equals(cloudId)).findFirst().get();

            AgedmallFreightTemplate freightTemplate = agedmallFreightTemplateService.findById(beChooseCloud.getModelDeliveryId().longValue());
            List<ExpressFreightTemplate> expressFreightTemplates = JSONObject.parseArray(freightTemplate.getExpressTemplate(), ExpressFreightTemplate.class);
            ExpressFreightTemplate template = null;
            for (ExpressFreightTemplate expressFreightTemplate : expressFreightTemplates) {
                String[] regionArr = expressFreightTemplate.getRegion().split(",");
                if (ArrayUtils.contains(regionArr,litemallAddress.getProvinceId() + "")) {
                    template = expressFreightTemplate;
                    break;
                }
            }
            // 不支持此区域
            if (null == template && litemallAddress.getProvinceId() != null) {
                return true;
            }
        }
        return false;
    }

    /**
     * 同城送取是否超出范围
     *
     * @return
     */
    public boolean SameCityIsDelivery(StoreGoodsVo storeGoodsVo, LitemallAddress litemallAddress) {
        AgedmallStore store = agedmallStoreService.findStoreById(storeGoodsVo.getStoreId());
//            // 实际配送距离
        GlobalCoordinates source = new GlobalCoordinates(litemallAddress.getLat().doubleValue(), litemallAddress.getLng().doubleValue());
        GlobalCoordinates target = new GlobalCoordinates(store.getLat().doubleValue(), store.getLng().doubleValue());
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.Sphere, source, target);
        double distance = geoCurve.getEllipsoidalDistance();
        logger.debug("总距离{}米", distance);
        BigDecimal meter = new BigDecimal(distance / 1000);
        logger.debug("总距离{}公里", meter);

        Integer logisticsType = storeGoodsVo.getLogisticsType();
        if (logisticsType != null && 1 == storeGoodsVo.getLogisticsType()) {
            AgedmallFreightTemplate freightTemplate = null;
            //物流
            Integer sameCitySendType = storeGoodsVo.getSameCitySendType();
            if (sameCitySendType != null && sameCitySendType == 0) {
                Integer express = storeGoodsVo.getExpress();
                if (express != null) {
                    freightTemplate = agedmallFreightTemplateService.findById(express.longValue());
                }
            }
            //自营
            else {
                Integer sameCity = storeGoodsVo.getSameCity();
                if (sameCity != null) {
                    freightTemplate = agedmallFreightTemplateService.findById(sameCity.longValue());
                }
            }

            // 按区域配送
            if (freightTemplate != null) {
                Integer payType = freightTemplate.getPayType();
                BigDecimal deliverRange = freightTemplate.getDeliveryRange();
                if (payType != null && 1 == payType) {
                    // 超出配送范围
                    if (deliverRange != null && deliverRange.compareTo(meter) < 0) {
                        return true;
                    }
                    // 按距离配送
                    // sunj todo 计算两点实际距离，而非直线距离
                } else {
                    // 未超出配送范围
                    if (deliverRange != null && deliverRange.compareTo(meter) < 0) {
                        return true;
                    }
                }
            }
        } else {
            BigDecimal distributionRange = store.getDistributionRange();
            if (distributionRange != null && distributionRange.compareTo(meter) < 0) {
                return true;
            }
        }
        return false;
    }

    public List<ReadmeVo> getReadmeList(List<ExplainDto> explainDtos) {
        List<ReadmeVo> readmeList = new ArrayList<>();
        List<AgedmallExplain> agedmallExplains = agedmallExplainService.findByStoreIds(explainDtos);
        for (AgedmallExplain agedmallExplain : agedmallExplains) {
            List<ExplainOrderContentInfo> infos = JSON.parseArray(agedmallExplain.getPlaceOrderContent(), ExplainOrderContentInfo.class);
            for (ExplainOrderContentInfo info : infos) {
                ReadmeVo readmeVo = new ReadmeVo();
                readmeVo.setTitle(info.getKey());
                readmeVo.setDesc(info.getValue());
                readmeList.add(readmeVo);
            }
        }
//        // 预付金
//        String payment = SystemConfig.getLitemallReadmePayment();
//        if (StringUtils.isNoneEmpty(payment)) {
//            ReadmeVo readmeVo = JSONObject.parseObject(payment, ReadmeVo.class);
//            readmeList.add(readmeVo);
//        }
//        // 活动
//        String activity = SystemConfig.getLitemallReadmeActivity();
//        if (StringUtils.isNoneEmpty(activity)) {
//            ReadmeVo readmeVo = JSONObject.parseObject(activity, ReadmeVo.class);
//            readmeList.add(readmeVo);
//        }
//        // 结算
//        String settle = SystemConfig.getLitemallReadmeSettle();
//        if (StringUtils.isNoneEmpty(settle)) {
//            ReadmeVo readmeVo = JSONObject.parseObject(settle, ReadmeVo.class);
//            readmeList.add(readmeVo);
//        }
        return readmeList;
    }

    private Map<String, Object> getStoreInfo(AgedmallStore store) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", store.getId());
        map.put("name", store.getStoreName());
        map.put("logo", store.getLogo());
        map.put("isSelf", store.getOwnOptFlg());
        return map;
    }


    public List<SubOrderGoodsVo> getGoodsList(List<LitemallOrderGoods> list) {
        List<Integer> storeGoodsIdList = list.parallelStream().map(LitemallOrderGoods::getStoreGoodsId).collect(Collectors.toList());
        List<Integer> productList = list.parallelStream().map(LitemallOrderGoods::getProductId).collect(Collectors.toList());
        List<StoreGoodsVo> storeGoodsVoList = agedmallStoreGoodsService.getStoreGoodsListByIds(storeGoodsIdList);
        List<StoreGoodsProductVo> storeGoodsProductVoList = agedmallStoreGoodsService.getStoreGoodsProductListByProductIds(productList);
        Map<Integer, List<StoreGoodsVo>> storeGoodsVoMap = storeGoodsVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsVo::getStoreGoodsId));
        Map<Integer, List<StoreGoodsProductVo>> storeGoodsProductVoMap = storeGoodsProductVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsProductVo::getId));
        Map<String, List<StoreGoodsProductVo>> storeGoodsProductStoreTypeKeyMap = new HashMap<>();
        storeGoodsProductVoList.stream().forEach(sg -> {
            int storeId = sg.getStoreId().intValue();
            int goodsId = sg.getGoodsId();
            String type = sg.getType();
            String key = storeId + "#" + goodsId + "#" + type;
            List<StoreGoodsProductVo> sList = storeGoodsProductStoreTypeKeyMap.get(key);
            if (sList == null) {
                sList = new ArrayList<>();
                storeGoodsProductStoreTypeKeyMap.put(key, sList);
            }
            sList.add(sg);
        });
        List<Integer> chargeTemolateIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getLeaseChargeTemolateId).collect(Collectors.toList());
        List<AgedmallChargeTemplate> agedmallChargeTemplateList = agedmallChargeTemplateService.findByIds(chargeTemolateIdList);
        Map<Integer, List<AgedmallChargeTemplate>> chargeTemplateMap = agedmallChargeTemplateList.parallelStream().collect(Collectors.groupingBy(AgedmallChargeTemplate::getId));

        int goodsStoreId = list.get(0).getStoreId();
        AgedmallStore store = agedmallStoreService.findStoreById(goodsStoreId);

        List<AgedmallHospitalSend> hospitalSends = agedmallHospitalSendService.getListByStoreGoodsIds(storeGoodsIdList);
        Map<Integer, List<AgedmallHospitalSend>> hospitalSendMap = new HashMap<>();
        hospitalSends.stream().forEach(hs -> {
            String storeIds = hs.getStoreIds();
            String[] storeIdArr = storeIds.split(",");
            Arrays.stream(storeIdArr).forEach(storeId -> {
                int sId = Integer.parseInt(storeId);
                List<AgedmallHospitalSend> hList = hospitalSendMap.get(sId);
                if (hList == null) {
                    hList = new ArrayList<>();
                    hospitalSendMap.put(sId, hList);
                }
                hList.add(hs);
            });
        });

        List<Integer> goodsIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsDeductionConf> goodsDeductionConfList = agedmallGoodsDeductionConfService.findDeductionListByGoodsIds(goodsIdList);
        Map<Integer, List<AgedmallGoodsDeductionConf>> goodsDeductionConfMap = goodsDeductionConfList.parallelStream().collect(Collectors.groupingBy(AgedmallGoodsDeductionConf::getGoodsId));

        List<String> childOrderCodeList = list.parallelStream().map(LitemallOrderGoods::getChildOrderCode).collect(Collectors.toList());
        List<AgedmallDeductDetail> deductDetailList = agedmallDeductDetailService.getListByOrderCode(childOrderCodeList);
        Map<String, AgedmallDeductDetail> deductDetailMap = new HashMap<>();
        deductDetailList.stream().forEach(d -> {
            String childOrderCode = d.getSubOrderSn();
            int goodsId = d.getGoodsId();
            String key = childOrderCode + "#" + goodsId;
            deductDetailMap.put(key, d);
        });

        List<Integer> orderGoodsIdList = list.parallelStream().map(LitemallOrderGoods::getId).collect(Collectors.toList());
        List<LitemallAftersale> aftersaleList = litemallAftersaleService.findListByOrderGoodsIds(orderGoodsIdList);
        Map<Integer, List<LitemallAftersale>> aftersaleMap = aftersaleList.parallelStream().collect(Collectors.groupingBy(LitemallAftersale::getOrderGoodsId));

        //StoreGoodsVo 的id
        List<Integer> storeGoodsVoIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsSpecificationInfo> customSpecList = agedmallGoodsSpecificationInfoService.getListByGoodsIds(storeGoodsVoIdList);
        List<Integer> specIdList = new ArrayList<>();
        Map<String, List<AgedmallGoodsSpecificationInfo>> goodsSpecificationMap = new HashMap<>();
        customSpecList.stream().forEach(cs -> {
            int goodsId = cs.getGoodsId();
            String type = cs.getType();
            String key = goodsId + "#" + type;
            List<AgedmallGoodsSpecificationInfo> sList = goodsSpecificationMap.get(key);
            if (sList == null) {
                sList = new ArrayList<>();
                goodsSpecificationMap.put(key, sList);
            }
            sList.add(cs);
            specIdList.add(cs.getId());
        });

        List<Integer> storeIdList = new ArrayList<>();
        storeIdList.add(goodsStoreId);
        List<AgedmallPartsVo> agedmallPartsVoList = litemallGoodsService.queryPartsList(specIdList, storeIdList);
        Map<String, List<AgedmallPartsVo>> agedmallPartsMap = new HashMap<>();
        agedmallPartsVoList.stream().forEach(pt -> {
            int specId = pt.getSpecId();
            int storeId = pt.getStoreId();
            String key = specId + "#" + storeId;
            List<AgedmallPartsVo> ptList = agedmallPartsMap.get(key);
            if (ptList == null) {
                ptList = new ArrayList<>();
                agedmallPartsMap.put(key, ptList);
            }
            ptList.add(pt);
        });

        List<LitemallGoodsSpecification> goodsSpecificationList = litemallGoodsSpecificationService.queryListByParentIds(specIdList);
        Map<Integer, List<LitemallGoodsSpecification>> goodsChildSpecificationMap = goodsSpecificationList.parallelStream().collect(Collectors.groupingBy(LitemallGoodsSpecification::getParentId));

        List<AgedmallPartsVo> servicePartsVoList = litemallGoodsService.queryServicesList(specIdList);
        Map<Integer, List<AgedmallPartsVo>> servicePartsMap = servicePartsVoList.parallelStream().collect(Collectors.groupingBy(AgedmallPartsVo::getSpecId));

        List<AgedmallCloudGoodsProduct> cloudGoodsProductList = agedmallCloudHouseService.getCloudGoodsProductListByGoodsIds(storeGoodsVoIdList);
        Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap = cloudGoodsProductList.parallelStream().collect(Collectors.groupingBy(AgedmallCloudGoodsProduct::getGoodsId));

        return getGoodsList(list, storeGoodsVoMap, storeGoodsProductVoMap, new ArrayList<>(), chargeTemplateMap, hospitalSendMap, store, goodsDeductionConfMap, deductDetailMap, aftersaleMap, goodsSpecificationMap, agedmallPartsMap, goodsChildSpecificationMap, servicePartsMap, cloudGoodsProductMap, storeGoodsProductStoreTypeKeyMap);
    }

    public List<SubOrderGoodsVo> getGoodsList(List<LitemallOrderGoods> list, Map<Integer, List<StoreGoodsVo>> storeGoodsVoMap, Map<Integer, List<StoreGoodsProductVo>> storeGoodsProductVoMap, List<AgedmallServiceOrder> services,
                                              Map<Integer, List<AgedmallChargeTemplate>> chargeTemplateMap, Map<Integer, List<AgedmallHospitalSend>> hospitalSendMap, AgedmallStore store, Map<Integer,
            List<AgedmallGoodsDeductionConf>> goodsDeductionConfMap, Map<String, AgedmallDeductDetail> deductDetailMap, Map<Integer, List<LitemallAftersale>> aftersaleMap,
                                              Map<String, List<AgedmallGoodsSpecificationInfo>> specificationMap, Map<String, List<AgedmallPartsVo>> agedmallPartsMap,
                                              Map<Integer, List<LitemallGoodsSpecification>> goodsChildSpecificationMap, Map<Integer, List<AgedmallPartsVo>> servicePartsMap,
                                              Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap, Map<String, List<StoreGoodsProductVo>> storeGoodsProductStoreTypeKeyMap) {
        List<SubOrderGoodsVo> goodsList = new ArrayList<>();
        // 商品列表
        List<LitemallOrderGoods> orderGoodsList = list.stream().filter(p -> OrderGoodsConstant.TYPE_GOODS.endsWith(p.getType())).collect(Collectors.toList());
        // 配件列表
        List<LitemallOrderGoods> partsList = list.stream().filter(p -> OrderGoodsConstant.TYPE_CUSTOM.endsWith(p.getType())).collect(Collectors.toList());
        Map<Integer, List<LitemallOrderGoods>> partsMap = partsList.stream().collect(Collectors.toMap(
                LitemallOrderGoods::getPartentId,
                p -> {
                    List<LitemallOrderGoods> carts = new ArrayList<>();
                    carts.add(p);
                    return carts;
                },
                (list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
                }
        ));
        // 服务列表
        List<LitemallOrderGoods> serviceList = list.stream().filter(p -> OrderGoodsConstant.TYPE_EXTEND.endsWith(p.getType())).collect(Collectors.toList());
        Map<Integer, List<LitemallOrderGoods>> serviceMap = serviceList.stream().collect(Collectors.toMap(
                LitemallOrderGoods::getPartentId,
                p -> {
                    List<LitemallOrderGoods> carts = new ArrayList<>();
                    carts.add(p);
                    return carts;
                },
                (list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
                }
        ));
        // 在线服务列表
        Map<Integer, List<AgedmallServiceOrder>> onlineServiceMap = services != null ? services.stream().collect(Collectors.groupingBy(AgedmallServiceOrder::getOrderGoodsId)) : new HashMap<>();

        orderGoodsList.forEach(p -> {
            SubOrderGoodsVo subOrderGoodsVo = new SubOrderGoodsVo();

            StoreGoodsVo info = storeGoodsVoMap.get(p.getStoreGoodsId()).get(0);
            StoreGoodsProductVo goodsProduct = storeGoodsProductVoMap.get(p.getProductId()).get(0);
            info.setSaleRetailPrice(goodsProduct.getSaleRetailPrice());

            GoodsBaseData goodsBaseData = goodsManager.getGoodsBase(info, p.getNumber(), chargeTemplateMap, hospitalSendMap, store, goodsDeductionConfMap);
            String deductDetailKey = p.getChildOrderCode() + "#" + p.getGoodsId();
            AgedmallDeductDetail deductDetail = deductDetailMap.get(deductDetailKey);
            if (null != deductDetail) {
                goodsBaseData.setDeductStatus(1);
            }
            subOrderGoodsVo.setGoodsBase(goodsBaseData);

            List<LitemallOrderGoods> parts = null == partsMap.get(p.getId()) ? new ArrayList<>() : partsMap.get(p.getId());
            List<LitemallOrderGoods> service = null == serviceMap.get(p.getId()) ? new ArrayList<>() : serviceMap.get(p.getId());
            List<AgedmallServiceOrder> onlineService = null == onlineServiceMap.get(p.getId()) ? new ArrayList<>() : onlineServiceMap.get(p.getId());
            SkuInfo skuInfo = getSkuInfo(info, p, parts, service, onlineService, specificationMap, agedmallPartsMap, goodsChildSpecificationMap, storeGoodsVoMap, servicePartsMap, cloudGoodsProductMap, storeGoodsProductStoreTypeKeyMap, chargeTemplateMap);
            subOrderGoodsVo.setSkuInfo(skuInfo);

            BigDecimal partsPrice = parts.stream().map(LitemallOrderGoods::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal servicePrice = service.stream().map(LitemallOrderGoods::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal totalPrice = p.getPrice().add(partsPrice).add(servicePrice);
            subOrderGoodsVo.setTotalPrice(totalPrice.doubleValue());
            subOrderGoodsVo.setSaleUserId(null == p.getSaleUserId() ? null : Integer.parseInt(p.getSaleUserId()));

            List<LitemallAftersale> aftersaleList = aftersaleMap.get(p.getId());
            LitemallAftersale aftersale = aftersaleList != null ? aftersaleList.get(0) : null;
            subOrderGoodsVo.setAfterServiceInfo(AfterSaleInfoVo.getInstance(aftersale));

            subOrderGoodsVo.setGoodsLease(new GoodsLease(info.getCreditLease(), info.getCreditScore()));

            goodsList.add(subOrderGoodsVo);
        });
        return goodsList;
    }

    private SkuInfo getSkuInfo(StoreGoodsVo goods, LitemallOrderGoods orderGoods, List<LitemallOrderGoods> parts, List<LitemallOrderGoods> service,
                               List<AgedmallServiceOrder> serviceOrders, Map<String, List<AgedmallGoodsSpecificationInfo>> specificationMap,
                               Map<String, List<AgedmallPartsVo>> agedmallPartsMap, Map<Integer, List<LitemallGoodsSpecification>> goodsChildSpecificationMap,
                               Map<Integer, List<StoreGoodsVo>> storeGoodsVoMap, Map<Integer, List<AgedmallPartsVo>> servicePartsMap,
                               Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap, Map<String, List<StoreGoodsProductVo>> storeGoodsProductStoreTypeKeyMap,
                               Map<Integer, List<AgedmallChargeTemplate>> chargeTemplateMap) {
        SkuInfo skuInfo = new SkuInfo();
        GoodsSku goodsSku = goodsManager.getSkuItemList(goods, specificationMap, agedmallPartsMap, goodsChildSpecificationMap, storeGoodsVoMap, servicePartsMap, cloudGoodsProductMap, storeGoodsProductStoreTypeKeyMap, chargeTemplateMap);
        skuInfo.setGoodsSku(goodsSku);

        SelectedSpecInfo selectedGoodsSpec = new SelectedSpecInfo();
        selectedGoodsSpec.setId(orderGoods.getProductId());
        selectedGoodsSpec.setStock(orderGoods.getNumber().intValue());
        skuInfo.setSelectedGoodsSpec(selectedGoodsSpec);
        LitemallGoodsProduct goodsProduct=litemallGoodsProductService.findById(orderGoods.getProductId());
        LitemallOrderItem orderItem=litemallOrderItemMapper.selectByPrimaryKey(orderGoods.getChildOrderId().intValue());
        GoodsVipSalesDto selectProductVipSale = cartManager.getSelectProductVipSale(goodsProduct.getVipJson(),
                orderItem.getUserId(),orderGoods.getNumber().intValue(),goods.getVipPriceFlag());
        skuInfo.setSelectedSkuVipSale(selectProductVipSale);

        List<SelectedSpecInfo> selectedCustomSpecList = parts.stream()
                .map(p -> {
                    SelectedSpecInfo selectedSpecInfo = new SelectedSpecInfo();
                    selectedSpecInfo.setId(p.getStoreGoodsId());
                    selectedSpecInfo.setSkuId(p.getProductId());
                    selectedSpecInfo.setStock(p.getNumber().intValue());
                    return selectedSpecInfo;
                }).collect(Collectors.toList());
        skuInfo.setSelectedCustomSpec(selectedCustomSpecList);

        List<SelectedSpecInfo> selectedExtendSpecList = service.stream()
                .map(p -> {
                    SelectedSpecInfo selectedSpecInfo = new SelectedSpecInfo();
                    selectedSpecInfo.setId(p.getProductId());
                    selectedSpecInfo.setStock(p.getNumber().intValue());
                    return selectedSpecInfo;
                }).collect(Collectors.toList());
        skuInfo.setSelectedExtendSpec(selectedExtendSpecList);

        List<SelectedSpecInfo> selectedServiceSpec = serviceOrders.stream()
                .map(p -> {
                    SelectedSpecInfo selectedSpecInfo = new SelectedSpecInfo();
                    selectedSpecInfo.setId(p.getServiceId());
                    selectedSpecInfo.setSkuId(p.getServiceProductId());
                    selectedSpecInfo.setStock(1);
                    return selectedSpecInfo;
                }).collect(Collectors.toList());
        skuInfo.setSelectedServiceSpec(selectedServiceSpec);

        return skuInfo;
    }

    @Transactional
    public BaseResult cancel(Integer userId, String bigOrderCode, String reason) {
        return orderService.cancel(userId, bigOrderCode, reason);
    }

    @Transactional
    public BaseResult remove(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder order = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        OrderHandleOption orderHandleOption = OrderUtil.buildItem(orderItem);
        if (!orderHandleOption.isDelete()) {
            throw new BizException("订单状态不能删除");
        }
        orderItem.setDeleted(true);
        orderItem.setOrderStatus(OrderUtil.STATUS_CANCEL);
        litemallOrderService.updateItem(orderItem);

        // 删除子订单包含服务
        AgedmallServiceOrderExample serviceOrderExample = new AgedmallServiceOrderExample();
        serviceOrderExample.createCriteria().andDeletedEqualTo(false)
                .andSubOrderIdEqualTo(orderItem.getId());
        agedmallServiceOrderMapper.logicalDeleteByExample(serviceOrderExample);

        List<LitemallOrderItem> list = litemallOrderService.getOrderItemListByBigOrderCode(userId, bigOrderCode);
        if (CollectionUtils.isEmpty(list)) {
            order.setDeleted(true);
            order.setOrderStatus(OrderUtil.STATUS_CANCEL);
            litemallOrderService.update(order);
        } else {
            BigDecimal goodsPrice = list.stream().map(LitemallOrderItem::getGoodsPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal deliveryPrice = list.stream().map(LitemallOrderItem::getFreightPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            updateMainOrderPrice(order.getId(), goodsPrice, deliveryPrice);
        }
        return RespUtil.success();
    }

    public void updateMainOrderPrice(Integer orderId, BigDecimal goodsPrice, BigDecimal deliveryPrice) {
        BigDecimal freightPrice = deliveryPrice;
        BigDecimal couponPrice = BigDecimal.ZERO;
        BigDecimal integralPrice = BigDecimal.ZERO;
        BigDecimal grouponPrice = BigDecimal.ZERO;
        BigDecimal orderPrice = goodsPrice.add(freightPrice).subtract(couponPrice);
        BigDecimal actualPrice = orderPrice.subtract(integralPrice);

        LitemallOrder litemallOrder = new LitemallOrder();
        litemallOrder.setId(orderId);
        litemallOrder.setGoodsPrice(goodsPrice);
        litemallOrder.setFreightPrice(freightPrice);
        litemallOrder.setCouponPrice(couponPrice);
        litemallOrder.setIntegralPrice(integralPrice);
        litemallOrder.setGrouponPrice(grouponPrice);
        litemallOrder.setOrderPrice(orderPrice);
//        litemallOrder.setServicePrice(servicePrice);
        litemallOrder.setActualPrice(actualPrice);

        litemallOrderService.update(litemallOrder);
    }

    public BaseResult list(Integer userId, String keyword, String subOrderStatus, Integer isService, Integer page, Integer limit, String bigOrderId) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        //存放子订单状态的集合
        List<String> stats = StringUtils.isNotEmpty(subOrderStatus) ? Arrays.asList(subOrderStatus.split(",")) : new ArrayList<>();
        //stats.stream().map(p->Integer.parseInt(p)).collect(Collectors.toList());
        //对存放子订单号的集合进行转换成Int类型
        List<Integer> showTypeList = stats.stream().map(Integer::parseInt).collect(Collectors.toList());
        // List<Short> shortList = showTypeList.stream().map(p -> OrderUtil.orderStatus(p)).flatMap(Collection::stream).collect(Collectors.toList());
        List<Short> statList = showTypeList.stream().map(p -> OrderUtil.orderStatus(p)).flatMap(Collection::stream).collect(Collectors.toList());

        long startTime = System.currentTimeMillis();
        List<OrderListVo> orderListVos = new ArrayList<>();
        List<LitemallOrder> litemallOrderList = litemallOrderService.orderList(userId, keyword, statList, isService, page, limit, bigOrderId);
        if (litemallOrderList == null || litemallOrderList.size() == 0) {
            PageData<OrderListVo> pageData = new PageData<>();
            pageData.setNowPage(page);
            pageData.setTotalPage(0);
            pageData.setTotalRows(0);
            pageData.setRows(new ArrayList<>());
            return RespUtil.success(pageData);
        }
        List<Integer> bigOrderIdList = litemallOrderList.parallelStream().map(LitemallOrder::getId).collect(Collectors.toList());
        List<Long> bigOrderLongIdList = new ArrayList<>();
        bigOrderIdList.stream().forEach(id -> {
            bigOrderLongIdList.add(Long.parseLong(id.toString()));
        });
        List<LitemallOrderItem> orderItemList = litemallOrderService.queryOrderItemListByBigOrderIds(bigOrderIdList);
        List<LitemallOrderGoods> orderGoodsPageList = litemallOrderService.queryOrderGoodsByBigOrderIds(bigOrderIdList, isService);
        List<Integer> storeGoodsIdList = orderGoodsPageList.parallelStream().map(LitemallOrderGoods::getStoreGoodsId).distinct().collect(Collectors.toList());
        List<StoreGoodsVo> storeGoodsVoList = agedmallStoreGoodsService.getStoreGoodsListByIds(storeGoodsIdList);
        List<Integer> productList = orderGoodsPageList.parallelStream().map(LitemallOrderGoods::getProductId).distinct().collect(Collectors.toList());
        List<StoreGoodsProductVo> storeGoodsProductVoList = agedmallStoreGoodsService.getStoreGoodsProductListByProductIds(productList);
        List<Integer> storeIdList = orderGoodsPageList.parallelStream().map(LitemallOrderGoods::getStoreId).distinct().collect(Collectors.toList());
        List<Integer> extraStoreIdList = orderItemList.parallelStream().filter(oi -> oi.getExtractShop() != null).map(LitemallOrderItem::getStoreId).collect(Collectors.toList());
        storeIdList.addAll(extraStoreIdList);
        List<AgedmallStore> storeList = agedmallStoreService.getStoreListByIntIds(storeIdList);
        Map<Integer, List<StoreGoodsProductVo>> storeGoodsProductVoMap = storeGoodsProductVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsProductVo::getId));
        Map<String, List<StoreGoodsProductVo>> storeGoodsProductStoreTypeKeyMap = new HashMap<>();
        storeGoodsProductVoList.stream().forEach(sg -> {
            int storeId = sg.getStoreId().intValue();
            int goodsId = sg.getGoodsId();
            String type = sg.getType();
            String key = storeId + "#" + goodsId + "#" + type;
            List<StoreGoodsProductVo> list = storeGoodsProductStoreTypeKeyMap.get(key);
            if (list == null) {
                list = new ArrayList<>();
                storeGoodsProductStoreTypeKeyMap.put(key, list);
            }
            list.add(sg);
        });
        Map<Integer, List<StoreGoodsVo>> storeGoodsVoMap = storeGoodsVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsVo::getStoreGoodsId));
        Map<Long, List<AgedmallStore>> storeMap = storeList.parallelStream().collect(Collectors.groupingBy(AgedmallStore::getId));
        Map<Long, List<LitemallOrderGoods>> orderGoodsMap = orderGoodsPageList.parallelStream().collect(Collectors.groupingBy(LitemallOrderGoods::getChildOrderId));
        Map<Integer, List<LitemallOrderItem>> orderItemMap = orderItemList.parallelStream().collect(Collectors.groupingBy(LitemallOrderItem::getParentId));
        PageInfo<LitemallOrder> pagedList = PageInfo.of(litemallOrderList);
        logger.debug("-------------aaaaaaaaaa----{}>>{}", userId, (System.currentTimeMillis() - startTime));

        List<AgedmallServiceOrder> serviceList = new ArrayList<>();
        if (bigOrderLongIdList.size() > 0) {
            AgedmallServiceOrderExample serviceOrderExample = new AgedmallServiceOrderExample();
            serviceOrderExample.createCriteria().andDeletedEqualTo(false)
                    .andOrderIdIn(bigOrderLongIdList);
            serviceList = agedmallServiceOrderMapper.selectByExample(serviceOrderExample);
        }
        Map<Long, List<AgedmallServiceOrder>> serviceOrderMap = serviceList.parallelStream().collect(Collectors.groupingBy(AgedmallServiceOrder::getOrderId));

        List<AgedmallLeaseGoodsReturnRecord> returnRecordList = agedmallLeaseGoodsReturnRecordService.findByOrderIds(bigOrderLongIdList);
        Map<String, AgedmallLeaseGoodsReturnRecord> returnRecordMap = new HashMap<>();
        returnRecordList.stream().forEach(r -> {
            String itemOrderIds = r.getSubOrderIds();
            String[] arr = itemOrderIds.split(",");
            String key = r.getBigOrderId() + "#";
            Arrays.stream(arr).forEach(itemId -> returnRecordMap.put((key + itemId), r));
        });

        List<Integer> chargeTemolateIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getLeaseChargeTemolateId).collect(Collectors.toList());
        List<AgedmallChargeTemplate> agedmallChargeTemplateList = agedmallChargeTemplateService.findByIds(chargeTemolateIdList);
        Map<Integer, List<AgedmallChargeTemplate>> chargeTemplateMap = agedmallChargeTemplateList.parallelStream().collect(Collectors.groupingBy(AgedmallChargeTemplate::getId));

        List<AgedmallHospitalSend> hospitalSends = agedmallHospitalSendService.getListByStoreGoodsIds(storeGoodsIdList);
        Map<Integer, List<AgedmallHospitalSend>> hospitalSendMap = new HashMap<>();
        hospitalSends.stream().forEach(hs -> {
            String storeIds = hs.getStoreIds();
            String[] storeIdArr = storeIds.split(",");
            Arrays.stream(storeIdArr).forEach(storeId -> {
                int sId = Integer.parseInt(storeId);
                List<AgedmallHospitalSend> hList = hospitalSendMap.get(sId);
                if (hList == null) {
                    hList = new ArrayList<>();
                    hospitalSendMap.put(sId, hList);
                }
                hList.add(hs);
            });
        });

        List<Integer> goodsIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsDeductionConf> goodsDeductionConfList = agedmallGoodsDeductionConfService.findDeductionListByGoodsIds(goodsIdList);
        Map<Integer, List<AgedmallGoodsDeductionConf>> goodsDeductionConfMap = goodsDeductionConfList.parallelStream().collect(Collectors.groupingBy(AgedmallGoodsDeductionConf::getGoodsId));

        logger.debug("-------------bbbbbbbbbb----{}>>{}", userId, (System.currentTimeMillis() - startTime));

        List<String> childOrderCodeList = orderItemList.parallelStream().map(LitemallOrderItem::getChildOrderCode).collect(Collectors.toList());
        List<AgedmallDeductDetail> deductDetailList = agedmallDeductDetailService.getListByOrderCode(childOrderCodeList);
        Map<String, AgedmallDeductDetail> deductDetailMap = new HashMap<>();
        deductDetailList.stream().forEach(d -> {
            String childOrderCode = d.getSubOrderSn();
            int goodsId = d.getGoodsId();
            String key = childOrderCode + "#" + goodsId;
            deductDetailMap.put(key, d);
        });

        List<Integer> orderGoodsIdList = orderGoodsPageList.parallelStream().map(LitemallOrderGoods::getId).collect(Collectors.toList());
        List<LitemallAftersale> aftersaleList = litemallAftersaleService.findListByOrderGoodsIds(orderGoodsIdList);
        Map<Integer, List<LitemallAftersale>> aftersaleMap = aftersaleList.parallelStream().collect(Collectors.groupingBy(LitemallAftersale::getOrderGoodsId));

        //StoreGoodsVo 的id
        List<Integer> storeGoodsVoIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsSpecificationInfo> customSpecList = agedmallGoodsSpecificationInfoService.getListByGoodsIds(storeGoodsVoIdList);
        List<Integer> specIdList = new ArrayList<>();
        Map<String, List<AgedmallGoodsSpecificationInfo>> goodsSpecificationMap = new HashMap<>();
        customSpecList.stream().forEach(cs -> {
            int goodsId = cs.getGoodsId();
            String type = cs.getType();
            String key = goodsId + "#" + type;
            List<AgedmallGoodsSpecificationInfo> sList = goodsSpecificationMap.get(key);
            if (sList == null) {
                sList = new ArrayList<>();
                goodsSpecificationMap.put(key, sList);
            }
            sList.add(cs);
            specIdList.add(cs.getId());
        });


        List<AgedmallPartsVo> agedmallPartsVoList = litemallGoodsService.queryPartsList(specIdList, storeIdList);
        Map<String, List<AgedmallPartsVo>> agedmallPartsMap = new HashMap<>();
        agedmallPartsVoList.stream().forEach(pt -> {
            int specId = pt.getSpecId();
            int storeId = pt.getStoreId();
            String key = specId + "#" + storeId;
            List<AgedmallPartsVo> ptList = agedmallPartsMap.get(key);
            if (ptList == null) {
                ptList = new ArrayList<>();
                agedmallPartsMap.put(key, ptList);
            }
            ptList.add(pt);
        });

        logger.debug("-------------cccccccccc----{}>>{}", userId, (System.currentTimeMillis() - startTime));

        List<LitemallGoodsSpecification> goodsSpecificationList = litemallGoodsSpecificationService.queryListByParentIds(specIdList);
        Map<Integer, List<LitemallGoodsSpecification>> goodsChildSpecificationMap = goodsSpecificationList.parallelStream().collect(Collectors.groupingBy(LitemallGoodsSpecification::getParentId));

        List<AgedmallPartsVo> servicePartsVoList = litemallGoodsService.queryServicesList(specIdList);
        Map<Integer, List<AgedmallPartsVo>> servicePartsMap = servicePartsVoList.parallelStream().collect(Collectors.groupingBy(AgedmallPartsVo::getSpecId));

        List<AgedmallCloudGoodsProduct> cloudGoodsProductList = agedmallCloudHouseService.getCloudGoodsProductListByGoodsIds(storeGoodsVoIdList);
        Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap = cloudGoodsProductList.parallelStream().collect(Collectors.groupingBy(AgedmallCloudGoodsProduct::getGoodsId));

        logger.debug("-------------dddddddddd----{}>>{}", userId, (System.currentTimeMillis() - startTime));

        //---------------------------------------------------------------------------------

        for (LitemallOrder bigOrder : litemallOrderList) {
            Integer orderId = bigOrder.getId();
            // 获取订单下后付服务

            List<AgedmallServiceOrder> services = serviceOrderMap.get(orderId.longValue());

            OrderListVo orderListVo = new OrderListVo(bigOrder);
            orderListVo.setCreditLeaseMaxPrice(new BigDecimal(SystemConfig.getLitemallCreditLeaseMaxPrice()));
            List<SubOrderListVo> subOrderListVos = new ArrayList<>();
            List<LitemallOrderItem> subOrderList = orderItemMap.get(orderId);
            for (LitemallOrderItem litemallOrder : subOrderList) {
                List<LitemallOrderGoods> orderGoodsList = orderGoodsMap.get(Long.parseLong(litemallOrder.getId().toString()));
                SubOrderListVo subOrderListVo = new SubOrderListVo();
                //TODO 目前只有微信支付  后面可能有其他支付方式
                subOrderListVo.setPayChannel(0);
                subOrderListVo.setId(litemallOrder.getId());
                subOrderListVo.setIsCredit(litemallOrder.getIsCredit());
                subOrderListVo.setSubOrderId(litemallOrder.getChildOrderCode());
                subOrderListVo.setSubOrderStatus(OrderUtil.showType(litemallOrder.getOrderStatus()));
                subOrderListVo.setSubOrderPrice(litemallOrder.getActualPrice().doubleValue());
                subOrderListVo.setIsPay(StringUtils.isNotEmpty(bigOrder.getPayId()) ? 1 : 0);
                AgedmallStore store = storeMap.get(litemallOrder.getStoreId().longValue()).get(0);
                subOrderListVo.setStoreInfo(GoodsStoreInfo.getInstance(store));

                String extractType="none";
                if (null != litemallOrder.getExtractShop()) {


                    String dateTimeString = "请在  内自提，否则订单将取消";
                    String dateFormat = "";
                    LocalDateTime subTime = LocalDateTime.now();
                    String cancelRuleName = "自提取消规则";
                    //默认为24小时候




                    if (litemallOrder.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_SELF)) {
                        //如果是正常门店自提，区分是否是软链锁库存
                        if(orderGoodsList.get(0).getStockType()==1){
                            extractType="store_lock";
                        }
                        else{
                            extractType="store_base";
                        }
                        subTime = litemallOrder.getAddTime();
                    } else if (litemallOrder.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
                        JSONObject jsonObject = JSON.parseObject(litemallOrder.getDeliveryChoose());
                        String type = (String) jsonObject.get("type");
                        if (type.equals("subHospitalSelf")) {

                            if(orderGoodsList.get(0).getHospitalSelfLocationId()!=null
                            &&orderGoodsList.get(0).getLocationType()==0){
                                extractType="hospital_base";
                            }
                            else{
                                extractType="hospital_lock";
                            }
                        }
                        if (type.equals("subStoreSelf") || type.equals("subHospitalSelf")) {
                            JSONObject hosJSON = JSON.parseObject(litemallOrder.getDeliveryChoose());
                            String date = (String) hosJSON.get("date") + " " + (String) hosJSON.get("endTime") + ":00";
                            subTime = cn.hutool.core.date.DateUtil.parseLocalDateTime(date);
                            cancelRuleName = "预约自提规则";
                        }
                    } else {
                        subTime = litemallOrder.getAddTime();
                    }

                    DateTime dateTime = cn.hutool.core.date.DateUtil.offsetDay(Date.from(subTime.atZone(ZoneId.systemDefault()).toInstant()), 1);
                    dateFormat = cn.hutool.core.date.DateUtil.formatDateTime(dateTime);
                    dateTimeString = "请在 " + dateFormat + " 内自提，否则订单将取消";


                    subOrderListVo.setExtractNotice(dateTimeString);

                }
                subOrderListVo.setExtractType(extractType);
                String returnRecordKey = orderListVo.getId() + "#" + litemallOrder.getId();
                AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord = returnRecordMap.get(returnRecordKey);
                if (null != agedmallLeaseGoodsReturnRecord) {
                    LeaseReturnInfoVo leaseReturnInfoVo = new LeaseReturnInfoVo();
                    leaseReturnInfoVo.setChannel(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle().intValue());
                    // 如果是上门取件，已上门 不能撤回
                    if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                        leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getUpdoorTime() ? 0 : 1);
                        // 如果是自行寄回，商家没有确认收货，都可撤回
                    } else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_SELF_EXPRESS.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                        leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getReceiveTime() ? 1 : 0);
                    }
                    // 如果是送货到店，商家没有确认收货，都可撤回
                    else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_TO_STORE.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                        leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getReceiveTime() ? 1 : 0);
                    }

                    subOrderListVo.setReturnInfo(leaseReturnInfoVo);
                }
                List<SubOrderGoodsVo> subOrderGoodsVos = getGoodsList(orderGoodsList, storeGoodsVoMap, storeGoodsProductVoMap, services, chargeTemplateMap, hospitalSendMap, store, goodsDeductionConfMap, deductDetailMap, aftersaleMap, goodsSpecificationMap, agedmallPartsMap, goodsChildSpecificationMap, servicePartsMap, cloudGoodsProductMap, storeGoodsProductStoreTypeKeyMap);
                subOrderListVo.setSubOrderGoodsList(subOrderGoodsVos);
                subOrderListVos.add(subOrderListVo);
            }
            orderListVo.setSubOrderList(subOrderListVos);
            orderListVos.add(orderListVo);
        }

        PageData<OrderListVo> pageData = new PageData<>();
        pageData.setNowPage(page);
        pageData.setTotalPage(pagedList.getPages());
        pageData.setTotalRows((int) pagedList.getTotal());
        pageData.setRows(orderListVos);
        return RespUtil.success(pageData);
    }

    public BaseResult subOrderDetail(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        //获取用户的大订单
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        // 获取订单下后付服务
        AgedmallServiceOrderExample serviceOrderExample = new AgedmallServiceOrderExample();
        serviceOrderExample.createCriteria().andDeletedEqualTo(false)
                .andOrderIdEqualTo(bigOrder.getId().longValue());
        List<AgedmallServiceOrder> services = agedmallServiceOrderMapper.selectByExample(serviceOrderExample);
        //获取子订单
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        //获取子订单商品信息
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.getOrderGoodsListByChildOrderCode(childOrderCode);
        List<Integer> storeGoodsIdList = orderGoodsList.parallelStream().map(LitemallOrderGoods::getStoreGoodsId).collect(Collectors.toList());
        List<Integer> productList = orderGoodsList.parallelStream().map(LitemallOrderGoods::getProductId).collect(Collectors.toList());
        List<StoreGoodsVo> storeGoodsVoList = agedmallStoreGoodsService.getStoreGoodsListByIds(storeGoodsIdList);
        Map<Integer, List<StoreGoodsVo>> storeGoodsVoMap = storeGoodsVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsVo::getStoreGoodsId));
        List<StoreGoodsProductVo> storeGoodsProductVoList = agedmallStoreGoodsService.getStoreGoodsProductListByProductIds(productList);
        Map<Integer, List<StoreGoodsProductVo>> storeGoodsProductVoMap = storeGoodsProductVoList.parallelStream().collect(Collectors.groupingBy(StoreGoodsProductVo::getId));
        Map<String, List<StoreGoodsProductVo>> storeGoodsProductStoreTypeKeyMap = new HashMap<>();
        storeGoodsProductVoList.stream().forEach(sg -> {
            int storeId = sg.getStoreId().intValue();
            int goodsId = sg.getGoodsId();
            String type = sg.getType();
            String key = storeId + "#" + goodsId + "#" + type;
            List<StoreGoodsProductVo> list = storeGoodsProductStoreTypeKeyMap.get(key);
            if (list == null) {
                list = new ArrayList<>();
                storeGoodsProductStoreTypeKeyMap.put(key, list);
            }
            list.add(sg);
        });

        List<Integer> chargeTemolateIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getLeaseChargeTemolateId).collect(Collectors.toList());
        List<AgedmallChargeTemplate> agedmallChargeTemplateList = agedmallChargeTemplateService.findByIds(chargeTemolateIdList);
        Map<Integer, List<AgedmallChargeTemplate>> chargeTemplateMap = agedmallChargeTemplateList.parallelStream().collect(Collectors.groupingBy(AgedmallChargeTemplate::getId));

        List<AgedmallHospitalSend> hospitalSends = agedmallHospitalSendService.getListByStoreGoodsIds(storeGoodsIdList);
        Map<Integer, List<AgedmallHospitalSend>> hospitalSendMap = new HashMap<>();
        hospitalSends.stream().forEach(hs -> {
            String storeIds = hs.getStoreIds();
            String[] storeIdArr = storeIds.split(",");
            Arrays.stream(storeIdArr).forEach(storeId -> {
                int sId = Integer.parseInt(storeId);
                List<AgedmallHospitalSend> hList = hospitalSendMap.get(sId);
                if (hList == null) {
                    hList = new ArrayList<>();
                    hospitalSendMap.put(sId, hList);
                }
                hList.add(hs);
            });
        });

        List<Integer> goodsIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsDeductionConf> goodsDeductionConfList = agedmallGoodsDeductionConfService.findDeductionListByGoodsIds(goodsIdList);
        Map<Integer, List<AgedmallGoodsDeductionConf>> goodsDeductionConfMap = goodsDeductionConfList.parallelStream().collect(Collectors.groupingBy(AgedmallGoodsDeductionConf::getGoodsId));

        List<String> childOrderCodeList = new ArrayList<>();
        childOrderCodeList.add(childOrderCode);
        List<AgedmallDeductDetail> deductDetailList = agedmallDeductDetailService.getListByOrderCode(childOrderCodeList);
        Map<String, AgedmallDeductDetail> deductDetailMap = new HashMap<>();
        deductDetailList.stream().forEach(d -> {
            String key = d.getSubOrderSn() + "#" + d.getGoodsId();
            deductDetailMap.put(key, d);
        });

        List<Integer> orderGoodsIdList = orderGoodsList.parallelStream().map(LitemallOrderGoods::getId).collect(Collectors.toList());
        List<LitemallAftersale> aftersaleList = litemallAftersaleService.findListByOrderGoodsIds(orderGoodsIdList);
        Map<Integer, List<LitemallAftersale>> aftersaleMap = aftersaleList.parallelStream().collect(Collectors.groupingBy(LitemallAftersale::getOrderGoodsId));

        //StoreGoodsVo 的id
        List<Integer> storeGoodsVoIdList = storeGoodsVoList.parallelStream().map(StoreGoodsVo::getId).collect(Collectors.toList());
        List<AgedmallGoodsSpecificationInfo> customSpecList = agedmallGoodsSpecificationInfoService.getListByGoodsIds(storeGoodsVoIdList);
        List<Integer> specIdList = new ArrayList<>();
        Map<String, List<AgedmallGoodsSpecificationInfo>> goodsSpecificationMap = new HashMap<>();
        customSpecList.stream().forEach(cs -> {
            int goodsId = cs.getGoodsId();
            String type = cs.getType();
            String key = goodsId + "#" + type;
            List<AgedmallGoodsSpecificationInfo> sList = goodsSpecificationMap.get(key);
            if (sList == null) {
                sList = new ArrayList<>();
                goodsSpecificationMap.put(key, sList);
            }
            sList.add(cs);
            specIdList.add(cs.getId());
        });

        List<Integer> storeIdList = orderGoodsList.parallelStream().map(LitemallOrderGoods::getStoreId).distinct().collect(Collectors.toList());
        List<AgedmallPartsVo> agedmallPartsVoList = litemallGoodsService.queryPartsList(specIdList, storeIdList);
        Map<String, List<AgedmallPartsVo>> agedmallPartsMap = new HashMap<>();
        agedmallPartsVoList.stream().forEach(pt -> {
            int specId = pt.getSpecId();
            int storeId = pt.getStoreId();
            String key = specId + "#" + storeId;
            List<AgedmallPartsVo> ptList = agedmallPartsMap.get(key);
            if (ptList == null) {
                ptList = new ArrayList<>();
                agedmallPartsMap.put(key, ptList);
            }
            ptList.add(pt);
        });

        List<LitemallGoodsSpecification> goodsSpecificationList = litemallGoodsSpecificationService.queryListByParentIds(specIdList);
        Map<Integer, List<LitemallGoodsSpecification>> goodsChildSpecificationMap = goodsSpecificationList.parallelStream().collect(Collectors.groupingBy(LitemallGoodsSpecification::getParentId));

        List<AgedmallPartsVo> servicePartsVoList = litemallGoodsService.queryServicesList(specIdList);
        Map<Integer, List<AgedmallPartsVo>> servicePartsMap = servicePartsVoList.parallelStream().collect(Collectors.groupingBy(AgedmallPartsVo::getSpecId));

        List<AgedmallCloudGoodsProduct> cloudGoodsProductList = agedmallCloudHouseService.getCloudGoodsProductListByGoodsIds(storeGoodsVoIdList);
        Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap = cloudGoodsProductList.parallelStream().collect(Collectors.groupingBy(AgedmallCloudGoodsProduct::getGoodsId));


        //-------------------------------------------------


        //获取商品的信息
        AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord = agedmallLeaseGoodsReturnRecordService.findByOrderIdAndSubOrderId(bigOrder.getId() + "", orderItem.getId() + "");

        SubOrderDetailVo subOrderDetailVo = new SubOrderDetailVo();
        subOrderDetailVo.setBigOrderId(bigOrder.getOrderSn());
        // 目前都是居家的订单，返回0即可
        subOrderDetailVo.setOrderType(0);
        subOrderDetailVo.setTotalPrice(bigOrder.getOrderPrice());

        //返回商店id和商品的类型
        List<ExplainDto> explainDtos = new ArrayList<>();
        ExplainDto explainDto = new ExplainDto(GoodsConstant.GOODS_TYPE_SALE.equals(orderItem.getGoodsType()) ? 1 : 0, orderItem.getStoreId());
        explainDtos.add(explainDto);
        //返回商品的描述信息
        List<ReadmeVo> readmeVos = getReadmeList(explainDtos);
        subOrderDetailVo.setReadmeList(readmeVos);
        //返回用户订单信息地址                                       子订单的详细信息
        UserAddressInfo userAddressInfo = UserAddressInfo.getInstance(bigOrder);
        //子订单的详细地址
        subOrderDetailVo.setUserAddress(userAddressInfo);
        //订单以及子订单的详细信息
        SubOrderDetailInfoVo subOrderDetailInfoVo = new SubOrderDetailInfoVo();
        //TODO 现在默认为微信支付  后续可能有其他支付情况
        subOrderDetailInfoVo.setPayChannel(0);
        subOrderDetailInfoVo.setIsCredit(bigOrder.getIsCredit());
        if (OrderUtil.STATUS_CREATE.equals(bigOrder.getOrderStatus())) {
            //对于未支付的订单  设置订单支付时间
            long parSecond = Timestamp.valueOf(bigOrder.getAddTime()).getTime() + SystemConfig.getOrderUnpaid() * 60 * 1000 - System.currentTimeMillis();
            subOrderDetailInfoVo.setPaySecond(parSecond / 1000);
        }
        if (OrderUtil.STATUS_SHIP.equals(orderItem.getOrderStatus()) || OrderUtil.STATUS_SHIP_SELF.equals(orderItem.getOrderStatus())) {
            if (null != orderItem.getShipTime()) {
                //待收货时间
                long confirmSecond = Timestamp.valueOf(orderItem.getShipTime()).getTime() + SystemConfig.getOrderUnconfirm() * 24 * 60 * 60 * 1000 - System.currentTimeMillis();
                subOrderDetailInfoVo.setConfirmSecond(confirmSecond / 1000);
            }
        }
        if (GoodsConstant.GOODS_TYPE_LEASE.equals(orderItem.getGoodsType())) {
            if (null != orderItem.getShipArriveTime()) {
                //租赁信息
                LeaseInfoVo leaseInfoVo = new LeaseInfoVo();
                //租赁天数
                int leaseDays = orderCalcService.calLeaseDays(orderItem.getShipArriveTime(), LocalDateTime.now());
                leaseInfoVo.setDay(leaseDays);
                //租赁费用
                BigDecimal goodsPrice = BigDecimal.ZERO;
                for (LitemallOrderGoods litemallOrderGoods : orderGoodsList) {
                    if (OrderGoodsConstant.TYPE_GOODS.equals(litemallOrderGoods.getType())) {
                        BigDecimal price = goodsManager.countRent(litemallOrderGoods.getStoreGoodsId(), litemallOrderGoods.getStoreId() + "", Long.valueOf(leaseDays),litemallOrderGoods.getRuleId());
                        //租赁的总费用
                        goodsPrice = goodsPrice.add(price.multiply(new BigDecimal(litemallOrderGoods.getNumber())));
                    } else {
                        goodsPrice = goodsPrice.add(litemallOrderGoods.getPrice().multiply(new BigDecimal(litemallOrderGoods.getNumber())));
                    }
                }
                //返回租赁的总价格
                leaseInfoVo.setPrice(goodsPrice);
//                leaseInfoVo.setPrice(goodsPrice.add(order.getFreightPrice()));
                //把租赁的商品信息添加到子订单中返回
                subOrderDetailInfoVo.setLeaseInfo(leaseInfoVo);
            }
        }

        //封装快递信息
        List<ExpressVo> expressList = new ArrayList<>();
        ExpressVo logistInfo = getLogistInfo(bigOrder.getOrderSn(), orderItem);

        expressList.add(logistInfo);
        subOrderDetailInfoVo.setExpressList(expressList);
        //返回信息
        subOrderDetailInfoVo.setSubOrderId(orderItem.getChildOrderCode());
        subOrderDetailInfoVo.setSubOrderStatus(OrderUtil.showType(orderItem.getOrderStatus()));
        subOrderDetailInfoVo.setSubOrderPrice(orderItem.getActualPrice());
        subOrderDetailInfoVo.setIsPay(StringUtils.isNotEmpty(bigOrder.getPayId()) ? 1 : 0);
        AgedmallStore store = agedmallStoreService.findStoreById(orderItem.getStoreId());
        subOrderDetailInfoVo.setStoreInfo(GoodsStoreInfo.getInstance(store));
        subOrderDetailInfoVo.setSubOrderGoodsList(getGoodsList(orderGoodsList, storeGoodsVoMap, storeGoodsProductVoMap, services, chargeTemplateMap, hospitalSendMap, store, goodsDeductionConfMap, deductDetailMap, aftersaleMap, goodsSpecificationMap, agedmallPartsMap, goodsChildSpecificationMap, servicePartsMap, cloudGoodsProductMap, storeGoodsProductStoreTypeKeyMap));
        subOrderDetailInfoVo.setSubOrderInfos(getsubOrderGroupInfoVoList(bigOrder, orderItem, orderGoodsList, agedmallLeaseGoodsReturnRecord));
        String extractType="none";
        if (null != orderItem.getExtractShop()) {

            String dateTimeString = "请在  内自提，否则订单将取消";
            String dateFormat = "";
            LocalDateTime subTime = LocalDateTime.now();
            String cancelRuleName = "自提取消规则";
            //默认为24小时候




            if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_SELF)) {
                //如果是正常门店自提，区分是否是软链锁库存
                if(orderGoodsList.get(0).getStockType()==1){
                    extractType="store_lock";
                }
                else{
                    extractType="store_base";
                }
                subTime = orderItem.getAddTime();
            } else if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
                JSONObject jsonObject = JSON.parseObject(orderItem.getDeliveryChoose());
                String type = (String) jsonObject.get("type");
                if (type.equals("subHospitalSelf")) {

                    if(orderGoodsList.get(0).getHospitalSelfLocationId()!=null
                            &&orderGoodsList.get(0).getLocationType()==0){
                        extractType="hospital_base";
                    }
                    else{
                        extractType="hospital_lock";
                    }
                }
                if (type.equals("subStoreSelf") || type.equals("subHospitalSelf")) {
                    JSONObject hosJSON = JSON.parseObject(orderItem.getDeliveryChoose());
                    String date = (String) hosJSON.get("date") + " " + (String) hosJSON.get("endTime") + ":00";
                    subTime = cn.hutool.core.date.DateUtil.parseLocalDateTime(date);
                    cancelRuleName = "预约自提规则";
                }
            } else {
                subTime = orderItem.getAddTime();
            }

            DateTime dateTime = cn.hutool.core.date.DateUtil.offsetDay(Date.from(subTime.atZone(ZoneId.systemDefault()).toInstant()), 1);
            dateFormat = cn.hutool.core.date.DateUtil.formatDateTime(dateTime);
            dateTimeString = "请在 " + dateFormat + " 内自提，否则订单将取消";


            subOrderDetailInfoVo.setExtractNotice(dateTimeString);
        }
        subOrderDetailInfoVo.setExtractType(extractType);

        if (null != agedmallLeaseGoodsReturnRecord) {
            LeaseReturnInfoVo leaseReturnInfoVo = new LeaseReturnInfoVo();
            leaseReturnInfoVo.setChannel(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle().intValue());
            // 如果是上门取件，已上门 不能撤回
            if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getUpdoorTime() ? 0 : 1);
                // 如果是自行寄回，商家没有确认收货，都可撤回
            } else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_SELF_EXPRESS.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getReceiveTime() ? 1 : 0);
            }
            // 如果是送货到店，商家没有确认收货，都可撤回
            else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_TO_STORE.equals(agedmallLeaseGoodsReturnRecord.getGetGoodsStyle())) {
                leaseReturnInfoVo.setCancel(null != agedmallLeaseGoodsReturnRecord.getReceiveTime() ? 1 : 0);
            }
            subOrderDetailInfoVo.setReturnInfo(leaseReturnInfoVo);
        }

        subOrderDetailVo.setSubOrderDetail(subOrderDetailInfoVo);
        return RespUtil.success(subOrderDetailVo);
    }

    private List<SubOrderGroupInfoVo> getsubOrderGroupInfoVoList(LitemallOrder bigOrder, LitemallOrderItem orderItem, List<LitemallOrderGoods> orderGoodsList, AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord) {
        LitemallOrderGoods orderGoods = orderGoodsList.stream().filter(p -> OrderGoodsConstant.TYPE_GOODS.equals(p.getType())).findFirst().get();
        List<SubOrderGroupInfoVo> subOrderGroupInfoVoList = new ArrayList<>();
        subOrderGroupInfoVoList.add(getOrderInfo(bigOrder, orderItem));
        int orderStatus = orderItem.getOrderStatus();
        if (OrderUtil.STATUS_CREATE == orderStatus) {
            subOrderGroupInfoVoList.add(getShipInfo(orderItem, orderGoods));
        }
        if (OrderUtil.STATUS_REFUND_CONFIRM == orderStatus
                || OrderUtil.STATUS_RETURN == orderStatus
                || OrderUtil.STATUS_RETURN_SELF == orderStatus
                || OrderUtil.STATUS_RETURN_SETTLE == orderStatus
                || OrderUtil.STATUS_RETURN_SUCCESS == orderStatus) {
            subOrderGroupInfoVoList.add(getReturnInfo(bigOrder, orderItem, agedmallLeaseGoodsReturnRecord));
            subOrderGroupInfoVoList.add(getLeaseInfo(bigOrder, orderItem, orderGoodsList));
            subOrderGroupInfoVoList.add(getSettleInfo(orderItem));
        }
        if (OrderUtil.STATUS_LEASE_CONFIRM == orderStatus
                || OrderUtil.STATUS_LEASE_AUTO_CONFIRM == orderStatus) {
            subOrderGroupInfoVoList.add(getLeaseInfo(bigOrder, orderItem, orderGoodsList));
        }
        return subOrderGroupInfoVoList;
    }

    private SubOrderGroupInfoVo getSettleInfo(LitemallOrderItem orderItem) {
        LeaseRefundData refundData = orderCalcService.calLeaseOrderSettlementRefund(orderItem.getOrderCode(), orderItem.getChildOrderCode());
        //应付租金
        BigDecimal rent = refundData.getRent();
        //应退金额
        BigDecimal refund = refundData.getRefundFee();
        //预付租金
        BigDecimal orderPrice = orderItem.getActualPrice();

        SubOrderGroupInfoVo subOrderGroupInfoVo = new SubOrderGroupInfoVo();
        subOrderGroupInfoVo.setName("结算信息");
        List<SubOrderGroupAttrVo> subOrderGroupAttrVoList = new ArrayList<>();
        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("预付租金", orderPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));
        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("应付租金", "￥" + rent.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));
        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("应退金额", "￥" + refund.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));

        if (null != orderItem.getRefundAmount()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("实退金额", "￥" + orderItem.getRefundAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));
        }
        if (null != orderItem.getRefundTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("退款时间", orderItem.getRefundTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (StringUtils.isNotEmpty(orderItem.getRefundType())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("退款途径", orderItem.getRefundType(), 0, null, null));
        }
        if (StringUtils.isNotEmpty(orderItem.getRefundPayId())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("交易号", orderItem.getRefundPayId(), 0, null, null));
        }

        subOrderGroupInfoVo.setList(subOrderGroupAttrVoList);
        return subOrderGroupInfoVo;
    }

    private SubOrderGroupInfoVo getLeaseInfo(LitemallOrder bigOrder, LitemallOrderItem order, List<LitemallOrderGoods> orderGoodsList) {
        SubOrderGroupInfoVo subOrderGroupInfoVo = new SubOrderGroupInfoVo();
        subOrderGroupInfoVo.setName("租赁信息");
        List<SubOrderGroupAttrVo> subOrderGroupAttrVoList = new ArrayList<>();

        LocalDateTime shipArriveTime = order.getShipArriveTime();
        LocalDateTime endTIme = LocalDateTime.now();
        AgedmallLeaseGoodsReturnRecord returnRecord = agedmallLeaseGoodsReturnRecordService.findByOrderIdAndSubOrderId(bigOrder.getId() + "", order.getId() + "");
        if (ObjectUtil.isNotEmpty(returnRecord)) {
            endTIme = returnRecord.getAddTime();
        }
        int days = orderCalcService.calLeaseDays(shipArriveTime, endTIme);
        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("使用时长", days + "天", 0, null, null));

        BigDecimal goodsPrice = BigDecimal.ZERO;
        for (LitemallOrderGoods litemallOrderGoods : orderGoodsList) {
            if (OrderGoodsConstant.TYPE_GOODS.equals(litemallOrderGoods.getType())) {
                BigDecimal price = goodsManager.countRent(litemallOrderGoods.getStoreGoodsId(), litemallOrderGoods.getStoreId() + "", Long.valueOf(days),litemallOrderGoods.getRuleId());
                goodsPrice = goodsPrice.add(price);
            } else {
                goodsPrice = goodsPrice.add(litemallOrderGoods.getPrice());
            }
        }

        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("当前租金", "￥" + goodsPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));
        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("送货费用", "￥" + order.getFreightPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(), 0, null, null));

        // todo sunj 活动减免运费
        subOrderGroupInfoVo.setList(subOrderGroupAttrVoList);
        return subOrderGroupInfoVo;
    }

    private SubOrderGroupInfoVo getReturnInfo(LitemallOrder bigOrder, LitemallOrderItem order, AgedmallLeaseGoodsReturnRecord returnRecord) {
        SubOrderGroupInfoVo subOrderGroupInfoVo = new SubOrderGroupInfoVo();
        subOrderGroupInfoVo.setName("归还信息");
        List<SubOrderGroupAttrVo> subOrderGroupAttrVoList = new ArrayList<>();

        subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("订单编号", order.getChildOrderCode(), 1, null, null));
        if (null == returnRecord) {
            return subOrderGroupInfoVo;
        }
        if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(returnRecord.getGetGoodsStyle())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("归还方式", "上门取件", 0, null, null));
            UserAddressInfo userAddressInfo = JSONObject.parseObject(returnRecord.getUserAddressInfo(), UserAddressInfo.class);
            if (null != userAddressInfo) {
                String detail = userAddressInfo.getDetail();
                detail = StringUtils.isNotBlank(detail) ? "(" + detail + ")" : "";
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("预约取件地址", userAddressInfo.getAddress() + detail + " <br/>" + userAddressInfo.getUserName() + " " + userAddressInfo.getPhone(), 1, null, null));
            }
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("预约取件时间", returnRecord.getDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + returnRecord.getTime(), 0, null, null));
        } else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_TO_STORE.equals(returnRecord.getGetGoodsStyle())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("归还方式", "送货到店", 0, null, null));
            if (null != returnRecord.getReceiveTime()) {
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("送货到店时间", returnRecord.getReceiveTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
            }
        } else if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_SELF_EXPRESS.equals(returnRecord.getGetGoodsStyle())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("归还方式", "自行寄回", 0, null, null));
            LogisticsInfo logisticsInfo = JSONObject.parseObject(returnRecord.getLogisticsInfo(), LogisticsInfo.class);
            if (null != logisticsInfo) {
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("提交物流时间", returnRecord.getAddTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("物流公司", logisticsInfo.getExpressName(), 0, null, null));
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("物流单号", logisticsInfo.getExpressId(), 1, null, null));
            }
        }
        if (null != returnRecord.getEndTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("归还成功时间", returnRecord.getEndTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }

        subOrderGroupInfoVo.setList(subOrderGroupAttrVoList);
        return subOrderGroupInfoVo;
    }

    private SubOrderGroupInfoVo getShipInfo(LitemallOrderItem order, LitemallOrderGoods orderGoods) {
        SubOrderGroupInfoVo subOrderGroupInfoVo = new SubOrderGroupInfoVo();
        subOrderGroupInfoVo.setName("配送信息");
        List<SubOrderGroupAttrVo> subOrderGroupAttrVoList = new ArrayList<>();

        if (StringUtils.isEmpty(order.getDeliverySn())) {
            return subOrderGroupInfoVo;
        }
        List<AgedmallGoodsShipTypeVo> voList = agedmallGoodsShipTypeService.getByGoodsAndStore(AgedmallShipDictConstant.TYPE_SHIP, orderGoods.getGoodsId(), orderGoods.getStoreId());
        AgedmallGoodsShipTypeVo agedmallGoodsShipTypeVo = voList.stream()
                .filter(p -> AgedmallShipDictConstant.SHIP_SN_NORMAL.equals(p.getShipSn()))
                .findFirst().orElse(null);
        BigDecimal normalPrice = BigDecimal.ZERO;
        if (null != agedmallGoodsShipTypeVo) {
            JSONObject rule = JSONObject.parseObject(agedmallGoodsShipTypeVo.getRule());
            normalPrice = new BigDecimal(rule.getInteger("price"));
        }
        AgedmallGoodsShipTypeVo shipTypeVo = agedmallGoodsShipTypeService.getByGoodsAndStoreAndShip(AgedmallShipDictConstant.TYPE_SHIP, orderGoods.getGoodsId(), orderGoods.getStoreId(), order.getDeliverySn());
        if (null == shipTypeVo) {
            return subOrderGroupInfoVo;
        }

        if (AgedmallShipDictConstant.SHIP_SN_NORMAL.equals(order.getDeliverySn())) {
            String price = normalPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("配送方式", shipTypeVo.getShipName() + " ￥" + price, 0, null, null));
        }
        if (AgedmallShipDictConstant.SHIP_SN_URGENT.equals(order.getDeliverySn())) {
            String price = normalPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            TempSubOrderParamDeliveryUrgent urgent = JSONObject.parseObject(order.getDeliveryChoose(), TempSubOrderParamDeliveryUrgent.class);
            String urgentPrice = "0";
            if (null != urgent && null != urgent.getPrice()) {
                urgentPrice = urgent.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            }
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("配送方式", shipTypeVo.getShipName() + " ￥" + price + "/感谢费￥" + urgentPrice, 0, null, null));
        }
        if (AgedmallShipDictConstant.SHIP_SN_SUBSCRIBE.equals(order.getDeliverySn())) {
            TempSubOrderParamDeliverySubscribe subscribe = JSONObject.parseObject(order.getDeliveryChoose(), TempSubOrderParamDeliverySubscribe.class);
            String subscribePrice = normalPrice.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            if (null != subscribe && null != subscribe.getPrice()) {
                subscribePrice = normalPrice.add(subscribe.getPrice()).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            }
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("配送方式", shipTypeVo.getShipName() + " ￥" + subscribePrice, 0, null, null));
        }
        if (AgedmallShipDictConstant.SHIP_SN_SELF.equals(order.getDeliverySn())) {
            TempSubOrderParamDeliverySelf self = JSONObject.parseObject(order.getDeliveryChoose(), TempSubOrderParamDeliverySelf.class);
            String selfPrice = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            if (null != self && null != self.getPrice()) {
                selfPrice = self.getPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
            }
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("配送方式", shipTypeVo.getShipName() + " ￥" + selfPrice, 0, null, null));
        }
        if (StringUtils.isNotEmpty(order.getUpfloor())) {
            TempSubOrderParamUpFloor upFloorService = JSONObject.parseObject(order.getUpfloor(), TempSubOrderParamUpFloor.class);
            if (null != upFloorService) {
                String desc = "";
                BigDecimal price = BigDecimal.ZERO;
                if (null != upFloorService.getPrice()) {
                    price = upFloorService.getPrice();
                }
                String priveStr = price.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString();
                desc = ("lift".equals(upFloorService.getType()) ? "全层电梯 " : "需要爬楼 ") + upFloorService.getLayer() + "楼 服务费：￥" + priveStr;
                subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("上楼服务", desc, 0, null, null));
            }
        }

        subOrderGroupInfoVo.setList(subOrderGroupAttrVoList);
        return subOrderGroupInfoVo;
    }

    private SubOrderGroupInfoVo getOrderInfo(LitemallOrder bigOrder, LitemallOrderItem orderItem) {
        SubOrderGroupInfoVo subOrderGroupInfoVo = new SubOrderGroupInfoVo();
        subOrderGroupInfoVo.setName("订单信息");
        List<SubOrderGroupAttrVo> subOrderGroupAttrVoList = new ArrayList<>();

        if (StringUtils.isNotEmpty(orderItem.getMessage())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("订单备注", orderItem.getMessage(), 0, null, null));
        }
        if (StringUtils.isNotEmpty(orderItem.getChildOrderCode())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("订单编号", orderItem.getChildOrderCode(), 1, null, null));
        }
        if (null != orderItem.getAddTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("创建时间", orderItem.getAddTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (StringUtils.isNotEmpty(bigOrder.getPayId())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("交易号", bigOrder.getPayId(), 0, null, null));
        }
        if (null != bigOrder.getPayTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("付款时间", bigOrder.getPayTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (null != orderItem.getShipTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("发货时间", orderItem.getShipTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (null != orderItem.getShipArriveTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("送达时间", orderItem.getShipArriveTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (OrderUtil.STATUS_CANCEL.equals(orderItem.getOrderStatus())) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("取消时间", orderItem.getUpdateTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (null != orderItem.getEndTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("关闭时间", orderItem.getEndTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (null != orderItem.getConfirmTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("确认收货时间", orderItem.getConfirmTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }
        if (null != orderItem.getFinishTime()) {
            subOrderGroupAttrVoList.add(new SubOrderGroupAttrVo("完成时间", orderItem.getFinishTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER), 0, null, null));
        }

        subOrderGroupInfoVo.setList(subOrderGroupAttrVoList);
        return subOrderGroupInfoVo;
    }

    @Transactional
    public BaseResult confirm(Integer userId, String bigOrderCode, String childOrderCode, boolean isSelf) {
        return orderService.confirmReceiptNormal(userId, bigOrderCode, childOrderCode, isSelf);
    }

    /**
     * 确认收货前判断物流是否完成
     *
     * @return
     */
    public boolean isFinishSubOrderLogistics(String bigOrderSn, Integer subOrderId) {
        AgedmallLgBaseInfoExample baseInfoExample = new AgedmallLgBaseInfoExample();
        baseInfoExample.or().andOrderCodeEqualTo(bigOrderSn);
        List<AgedmallLgBaseInfo> agedmallLgBaseInfos = agedmallLgBaseInfoMapper.selectByExampleWithBLOBs(baseInfoExample);
        for (int i = 0; i < agedmallLgBaseInfos.size(); i++) {
            List<Integer> orderGoodsIds = logisticBusiBaseServiceImpl.getorderGoodsIds(agedmallLgBaseInfos.get(i).getLgContent());
            logger.debug("确认订单获取的订单商品id {},{},{}", JSONObject.toJSONString(orderGoodsIds), bigOrderSn, subOrderId);
            LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsIds.get(0));
            logger.debug("确认订单获取的订单商品 {},{},{},{}", orderGoods.getChildOrderId(), agedmallLgBaseInfos.get(i).getLgIsOver()
                    , bigOrderSn, subOrderId);
            if (orderGoods.getChildOrderId().intValue() == subOrderId.intValue() && agedmallLgBaseInfos.get(i).getLgIsOver().equals(LgBaseInfoIsOverEnum.END.getCode())) {
                return true;
            }
        }
        return false;
    }

    @Transactional
    public BaseResult afterSaleSubmit(Integer userId, AfterSaleSubmitForm afterSaleSubmitForm) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        //获取用户的大订单
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, afterSaleSubmitForm.getBigOrderId());
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        //获取用户的二级顶顶那
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrder.getOrderSn(), afterSaleSubmitForm.getSubOrderId());
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderGoods orderGoods = orderGoodsService.getOrderGodosByOrderCodeAndGid(orderItem.getChildOrderCode(), Integer.parseInt(afterSaleSubmitForm.getGoodsId()));
        if (null == orderGoods) {
            return RespUtil.badArgumentValue();
        }
        Integer aftersaleDays = SystemConfig.getOrderAftersale();
        if (null != orderItem.getFinishTime() && orderItem.getFinishTime().plusDays(aftersaleDays).isBefore(LocalDateTime.now())) {
            throw new BizException("商品超出售后时间");
        }
        LitemallAftersale litemallAftersale = litemallAftersaleService.findByOrderGoodsId(orderGoods.getId());
        if (null != litemallAftersale && !AftersaleConstant.STATUS_INIT.equals(litemallAftersale.getStatus())) {
            throw new BizException("商品在售后中");
        }

        // 非待发货 只退商品费用。待发货状态 退配件费、服务费，最后一件商品退运费。
        BigDecimal aftersalePrice = orderGoods.getPrice().multiply(new BigDecimal(orderGoods.getNumber()));
        String priceDesc = "退款金额不包含定制服务、特色服务、运费";
        if (OrderUtil.STATUS_PAY.equals(orderItem.getOrderStatus())) {
            aftersalePrice = orderItem.getOrderPrice();
            priceDesc = "退款金额包含定制服务、特色服务。运费会由客服审核退回";
        }

        BackGoodsInfoForm backGoodsInfo = afterSaleSubmitForm.getBackGoodsInfo();
        // 添加售后表
        LitemallAftersale aftersale = new LitemallAftersale();
        aftersale.setAftersaleSn(agedmallOrderSerialService.getAftersaleSn());
        aftersale.setUserId(userId);
        aftersale.setOrderId(orderItem.getId());
        aftersale.setOrderGoodsId(orderGoods.getId());
        aftersale.setType(afterSaleSubmitForm.getType().shortValue());
        aftersale.setReason(afterSaleSubmitForm.getReason());
        aftersale.setComment(afterSaleSubmitForm.getRemark());
        aftersale.setStatus(AftersaleConstant.STATUS_REQUEST);
        aftersale.setAmount(aftersalePrice);
        if (afterSaleSubmitForm.getImages() != null && !afterSaleSubmitForm.getImages().isEmpty()) {
            aftersale.setPictures(afterSaleSubmitForm.getImages().toArray(new String[afterSaleSubmitForm.getImages().size()]));
        }
        aftersale.setReceived(1 == backGoodsInfo.getIsReceived());
        aftersale.setHandleTime(LocalDateTime.now());
        if (null == litemallAftersale) {
            litemallAftersaleService.add(aftersale);
        } else {
            aftersale.setId(litemallAftersale.getId());
            litemallAftersaleService.updateById(aftersale);
        }

        // 有归还物品，添加归还表
//        if (1 == backGoodsInfo.getIsBack()) {
        AgedmallReturnGoodsRecord returnGoodsRecord = new AgedmallReturnGoodsRecord();
        returnGoodsRecord.setAfterSaleId(aftersale.getId());
        returnGoodsRecord.setUid(userId.longValue());
        returnGoodsRecord.setOrderCode(orderItem.getChildOrderCode());
        returnGoodsRecord.setReturnType(afterSaleSubmitForm.getType().byteValue());
        returnGoodsRecord.setGoodsIds(afterSaleSubmitForm.getGoodsId());
        returnGoodsRecord.setGetGoodsStyle(backGoodsInfo.getChannel());
        returnGoodsRecord.setPrice(aftersalePrice);
        returnGoodsRecord.setPriceDesc(priceDesc);
        if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(backGoodsInfo.getChannel())) {
            returnGoodsRecord.setUserAddressInfo(null == backGoodsInfo.getUserAdrees() ? null : JSONObject.toJSONString(backGoodsInfo.getUserAdrees()));
        }
        agedmallReturnGoodsRecordService.add(returnGoodsRecord);
//        }
        return RespUtil.success();
    }

    @Transactional
    public BaseResult afterSaleCancel(Integer userId, String id) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallAftersale aftersale = litemallAftersaleService.findBySn(userId, id);
        if (null == aftersale) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem order = litemallOrderService.findItemOrderById(userId, aftersale.getOrderId());
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        AfterSaleHandleOption afterSaleHandleOption = AftersaleConstant.build(aftersale);
        if (!afterSaleHandleOption.isCancel()) {
            throw new BizException("售后不能取消");
        }

        LitemallOrderGoods orderGoods = orderGoodsService.findById(aftersale.getOrderGoodsId());
        // 交易完成 且超过七天，售后关闭
        Integer aftersaleDays = SystemConfig.getOrderAftersale();
        if (null != order.getFinishTime() && order.getFinishTime().plusDays(aftersaleDays).isBefore(LocalDateTime.now())) {
            aftersale.setStatus(AftersaleConstant.STATUS_CANCEL);
        } else {
            aftersale.setStatus(AftersaleConstant.STATUS_INIT);
        }

        litemallAftersaleService.updateById(aftersale);

        // 删除归还物品
        agedmallReturnGoodsRecordService.deleteByOrderSnAndGoodsId(order.getChildOrderCode(), orderGoods.getGoodsId() + "");
        return RespUtil.success();
    }

    @Transactional
    public BaseResult afterSaleUpdate(Integer userId, AfterSaleSubmitForm afterSaleSubmitForm) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallAftersale aftersale = litemallAftersaleService.findBySn(userId, afterSaleSubmitForm.getId());
        if (null == aftersale) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem order = litemallOrderService.findItemOrderById(userId, aftersale.getOrderId());
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderGoods orderGoods = orderGoodsService.findById(aftersale.getOrderGoodsId());
        if (null == orderGoods) {
            return RespUtil.badArgumentValue();
        }
        Integer aftersaleDays = SystemConfig.getOrderAftersale();
        if (null != order.getConfirmTime() && order.getConfirmTime().plusDays(aftersaleDays).isBefore(LocalDateTime.now())) {
            throw new BizException("商品超出售后时间");
        }
        AfterSaleHandleOption afterSaleHandleOption = AftersaleConstant.build(aftersale);
        if (!afterSaleHandleOption.isUpdate()) {
            throw new BizException("售后不能修改");
        }
        BackGoodsInfoForm backGoodsInfo = afterSaleSubmitForm.getBackGoodsInfo();
        // 修改售后表
        aftersale.setReason(afterSaleSubmitForm.getReason());
        aftersale.setComment(afterSaleSubmitForm.getRemark());
        aftersale.setStatus(AftersaleConstant.STATUS_REQUEST);
        if (afterSaleSubmitForm.getImages() != null && !afterSaleSubmitForm.getImages().isEmpty()) {
            aftersale.setPictures(afterSaleSubmitForm.getImages().toArray(new String[afterSaleSubmitForm.getImages().size()]));
        }
        aftersale.setHandleTime(LocalDateTime.now());
        aftersale.setReceived(1 == backGoodsInfo.getIsReceived());
        litemallAftersaleService.updateById(aftersale);
        // 删除老的物品归还数据
        agedmallReturnGoodsRecordService.deleteByOrderSnAndGoodsId(order.getChildOrderCode(), orderGoods.getGoodsId() + "");
        // 有归还物品，添加归还表
//        if (1 == backGoodsInfo.getIsBack()) {
        AgedmallReturnGoodsRecord returnGoodsRecord = new AgedmallReturnGoodsRecord();
        returnGoodsRecord.setUid(userId.longValue());
        returnGoodsRecord.setOrderCode(order.getChildOrderCode());
        returnGoodsRecord.setReturnType(aftersale.getType().byteValue());
        returnGoodsRecord.setGoodsIds(afterSaleSubmitForm.getGoodsId());
        returnGoodsRecord.setGetGoodsStyle(backGoodsInfo.getChannel());
        returnGoodsRecord.setPrice(orderGoods.getPrice());
        if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(backGoodsInfo.getChannel())) {
            returnGoodsRecord.setUserAddressInfo(JSONObject.toJSONString(backGoodsInfo.getUserAdrees()));
        }
        agedmallReturnGoodsRecordService.add(returnGoodsRecord);
//        }
        return RespUtil.success();
    }

    public BaseResult afterSaleDetail(Integer userId, String bigOrderCode, String childOrderCode, String orderGoodsId) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderGoods orderGoods = orderGoodsService.getOrderGodosByOrderCodeAndGid(childOrderCode, Integer.parseInt(orderGoodsId));
        if (null == orderGoods) {
            return RespUtil.badArgumentValue();
        }


        AgedmallStoreGoods storeGoods = agedmallStoreGoodsService.getById(orderGoods.getStoreGoodsId().longValue());
        AgedmallStore store = agedmallStoreService.findStoreById(storeGoods.getStoreId());
        LitemallAftersale litemallAftersale = litemallAftersaleService.findWithBLOBsByOrderGoodsId(orderGoods.getId());
        AfterSaleDetailVo afterSaleDetailVo = new AfterSaleDetailVo();
        afterSaleDetailVo.setProvince(store.getProvinceName());
        afterSaleDetailVo.setCity(store.getCityName());


        // 非待发货 只退商品费用。待发货状态 退配件费、服务费，最后一件商品退运费。
        BigDecimal aftersalePrice = orderGoods.getPrice().multiply(new BigDecimal(orderGoods.getNumber()));
        String priceDesc = "退款金额不包含定制服务、特色服务、运费";
        boolean isCanOnlyMoney = false;
        if (OrderUtil.STATUS_PAY.equals(orderItem.getOrderStatus())) {
            aftersalePrice = orderItem.getOrderPrice();
            priceDesc = "退款金额包含定制服务、特色服务。运费会由客服审核退回";
            isCanOnlyMoney = true;
        }


        //只退款
        AfterSaleAServiceSuportRefundVo refund = new AfterSaleAServiceSuportRefundVo(isCanOnlyMoney ? 1 : 0, aftersalePrice, priceDesc, ReturnGoodsResonListConstant.getReasonList());
        //退货退款
        AfterSaleAServiceSuportRefundVo returnRefund = new AfterSaleAServiceSuportRefundVo(1, aftersalePrice, priceDesc, ReturnGoodsResonListConstant.getReasonList());
        //换货
        AfterSaleAServiceSuportRefundVo replaceRefund = new AfterSaleAServiceSuportRefundVo(1, aftersalePrice, priceDesc, ReturnGoodsResonListConstant.getReasonList());


        AfterSaleAServiceSuportVo serviceSuport = new AfterSaleAServiceSuportVo();
        serviceSuport.setRefund(refund);
        serviceSuport.setReturnRefund(returnRefund);
        serviceSuport.setReplace(replaceRefund);
        afterSaleDetailVo.setServiceSuport(serviceSuport);

        if (null == litemallAftersale || AftersaleConstant.STATUS_INIT.equals(litemallAftersale.getStatus())) {
            afterSaleDetailVo.setIsService(0);
        } else {
            afterSaleDetailVo.setIsService(1);
            AfterSaleServiceDetailVo serviceDetail = new AfterSaleServiceDetailVo();
            serviceDetail.setId(litemallAftersale.getAftersaleSn());
            serviceDetail.setType(litemallAftersale.getType().intValue());
            serviceDetail.setStatus(litemallAftersale.getStatus().intValue());
            serviceDetail.setReason(litemallAftersale.getReason());
            serviceDetail.setRemark(litemallAftersale.getComment());
            serviceDetail.setServicePhone(store.getPhone());
            serviceDetail.setRejectText(litemallAftersale.getRejectReason());
            String[] picArr = litemallAftersale.getPictures();
            if (null != picArr) {
                List<AfterSaleServiceDetailImageVo> imageVos = Arrays.stream(picArr).map(AfterSaleServiceDetailImageVo::new).collect(Collectors.toList());
                serviceDetail.setImages(imageVos);
            }
            serviceDetail.setUpdated(litemallAftersale.getHandleTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER));
            serviceDetail.setStatusTime(litemallAftersale.getAddTime().format(org.linlinjava.litemall.db.util.DateUtil.DATE_TIME_FORMATTER));

            AgedmallReturnGoodsRecord agedmallReturnGoodsRecord = agedmallReturnGoodsRecordService.getByOrderCodeAndGoodsId(orderItem.getChildOrderCode(), orderGoods.getGoodsId() + "");
            AfterSaleServiceDetailBackGoodsInfoVo backGoodsInfoVo = new AfterSaleServiceDetailBackGoodsInfoVo();
            backGoodsInfoVo.setIsReceived(litemallAftersale.getReceived() ? 1 : 0);
            backGoodsInfoVo.setIsBack(litemallAftersale.getReceived() ? 1 : 0);
            if (null != agedmallReturnGoodsRecord) {
                if (litemallAftersale.getReceived()) {
                    backGoodsInfoVo.setChannel(agedmallReturnGoodsRecord.getGetGoodsStyle().intValue());
                    if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP.equals(agedmallReturnGoodsRecord.getGetGoodsStyle())) {
                        UserAddressInfo userAddressInfo = JSONObject.parseObject(agedmallReturnGoodsRecord.getUserAddressInfo(), UserAddressInfo.class);
                        backGoodsInfoVo.setUserAdrees(userAddressInfo);
                    }
                }

                if (ReturnGoodsRecordConstant.GET_GOODS_STYLE_SELF_EXPRESS.equals(agedmallReturnGoodsRecord.getGetGoodsStyle())) {
                    AfterSaleServiceDetailSelfPostInfoVo afterSaleServiceDetailSelfPostInfoVo = new AfterSaleServiceDetailSelfPostInfoVo();
                    afterSaleServiceDetailSelfPostInfoVo.setAddress(UserAddressInfo.getInstance(store));
                    SelfExpressLogisticsNoForm selfExpressLogisticsNoForm = JSONObject.parseObject(agedmallReturnGoodsRecord.getLogisticsInfo(), SelfExpressLogisticsNoForm.class);
                    if (null != selfExpressLogisticsNoForm) {
                        afterSaleServiceDetailSelfPostInfoVo.setExpressId(selfExpressLogisticsNoForm.getExpressId());
                        afterSaleServiceDetailSelfPostInfoVo.setExpressName(selfExpressLogisticsNoForm.getExpressName());
                        List<AfterSaleServiceDetailImageVo> images = selfExpressLogisticsNoForm.getImages().stream().map(AfterSaleServiceDetailImageVo::new).collect(Collectors.toList());
                        afterSaleServiceDetailSelfPostInfoVo.setImages(images);
                        afterSaleServiceDetailSelfPostInfoVo.setRemark(selfExpressLogisticsNoForm.getRemark());
                    }
                    serviceDetail.setSelfPostInfo(afterSaleServiceDetailSelfPostInfoVo);
                }

                if (AftersaleConstant.TYPE_GOODS_MISS == agedmallReturnGoodsRecord.getReturnType().shortValue()
                        || AftersaleConstant.TYPE_GOODS_NEEDLESS == agedmallReturnGoodsRecord.getReturnType().shortValue()) {
                    AfterSaleServiceDetailRefundInfoVo refundInfoVo = new AfterSaleServiceDetailRefundInfoVo();
                    refundInfoVo.setPrice(agedmallReturnGoodsRecord.getPrice());
                    refundInfoVo.setPriceDesc(agedmallReturnGoodsRecord.getPriceDesc());
                    refundInfoVo.setChannel(agedmallReturnGoodsRecord.getChannel());
                    refundInfoVo.setRefundCode(agedmallReturnGoodsRecord.getRefundCode());
                    serviceDetail.setRefundInfo(refundInfoVo);
                } else if (AftersaleConstant.TYPE_GOODS_REQUIRED == agedmallReturnGoodsRecord.getReturnType().shortValue()) {
                    AfterSaleServiceDetailReplaceInfoVo replaceInfoVo = new AfterSaleServiceDetailReplaceInfoVo();
                    replaceInfoVo.setExpressId(agedmallReturnGoodsRecord.getExpressCode());
                    replaceInfoVo.setExpressName(agedmallReturnGoodsRecord.getExpressName());
                    serviceDetail.setReplaceInfo(replaceInfoVo);
                }
            }

            serviceDetail.setBackGoodsInfo(backGoodsInfoVo);
            afterSaleDetailVo.setServiceDetail(serviceDetail);
        }
        return RespUtil.success(afterSaleDetailVo);
    }

    public BaseResult selfExpressLogisticsNo(Integer userId, SelfExpressLogisticsNoForm selfExpressLogisticsNoForm) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallAftersale litemallAftersale = litemallAftersaleService.findBySn(userId, selfExpressLogisticsNoForm.getId());
        if (null == litemallAftersale) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrder order = litemallOrderService.findById(userId, litemallAftersale.getOrderId());
        LitemallOrderGoods orderGoods = orderGoodsService.findById(litemallAftersale.getOrderGoodsId());
        AgedmallReturnGoodsRecord agedmallReturnGoodsRecord = agedmallReturnGoodsRecordService.getByOrderCodeAndGoodsId(order.getOrderSn(), orderGoods.getGoodsId() + "");
        LogisticsInfo logisticsInfo = selfExpressLogisticsNoForm;
        if (CollectionUtils.isNotEmpty(logisticsInfo.getImages())) {
            logisticsInfo.setImages(logisticsInfo.getImages());
        }
        agedmallReturnGoodsRecord.setLogisticsInfo(JSONObject.toJSONString(logisticsInfo));
        agedmallReturnGoodsRecordService.upadte(agedmallReturnGoodsRecord);

        litemallAftersale.setStatus(AftersaleConstant.STATUS_WAIT_RECEIVE);
        litemallAftersale.setHandleTime(LocalDateTime.now());
        litemallAftersaleService.updateById(litemallAftersale);

        // 添加售后节点
        agedmallOrderLogisticsService.addOrderLogistics(order.getId(), OrderLogisticsConstant.TYPE_AFTERSALE,
                litemallAftersale.getId() + "", OrderLogisticsConstant.DEFAULTEXPRESSNAME,
                OrderLogisticsConstant.AFTERSALE_TITLE_SELFEXPRESS, OrderLogisticsConstant.AFTERSALE_DESC_SELFEXPRESS);
        return RespUtil.success();
    }

    public BaseResult logisticsInfoList(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }

        // 发货物流

        ExpressVo logistInfo = getLogistInfo(bigOrder.getOrderSn(), orderItem);
        List<ExpressVo> expressVosList = new ArrayList<>();
        if (logistInfo.getExpressInfoList().size() == 0) {

            List<ExpressInfoVo> expressInfoVoList = new ArrayList<>();
            ExpressInfoVo expressInfoVo = new ExpressInfoVo();
            expressInfoVo.setId("10000");
            expressInfoVo.setTime(cn.hutool.core.date.DateUtil.formatLocalDateTime(orderItem.getAddTime()));
            expressInfoVo.setTitle("备货中");
            expressInfoVo.setDesc("商家正在备货中");
            expressInfoVoList.add(expressInfoVo);
            logistInfo.setExpressInfoList(expressInfoVoList);
            logistInfo.setExpressId("暂无信息");
            logistInfo.setExpressName("暂无信息");
        }
        expressVosList.add(logistInfo);

        return RespUtil.success(expressVosList);
    }

    public ExpressVo getLogistInfo(String bigOrderSn, LitemallOrderItem subOrder) {
        List<Long> baseInfoId = matchOrderAndLogistics(bigOrderSn, subOrder.getId());
        if (ObjectUtil.isNull(baseInfoId) || baseInfoId.size() == 0) {
            return null;
        }
        List<SaleLogisticsDto> logisticsMessage = appOrderMapper.getLogisticsMessage(baseInfoId);
        ExpressVo expressVo = new ExpressVo();
        boolean isThird = false;
        AgedmallLgThirdLogisRecord lgThirdLogisRecord = new AgedmallLgThirdLogisRecord();
        for (int i = 0; i < logisticsMessage.size(); i++) {
            if (logisticsMessage.get(i).getLgExecType() == 2 && logisticsMessage.get(i).getType() == 2) {
                isThird = true;
                AgedmallLgThirdLogisRecordExample recordExample = new AgedmallLgThirdLogisRecordExample();
                recordExample.createCriteria().andLgBusiIdEqualTo(logisticsMessage.get(i).getId().longValue());
                lgThirdLogisRecord = agedmallLgThirdLogisRecordMapper.selectOneByExample(recordExample);
            }
        }
        if (isThird) {
            expressVo.setExpressId(lgThirdLogisRecord.getThirdOrderCode());
            expressVo.setExpressName(lgThirdLogisRecord.getThirdLogisName());
        } else {
            expressVo.setExpressId(subOrder.getChildOrderCode());
            expressVo.setExpressName("老宝贝快递");
        }

        List<ExpressInfoVo> expressList = new ArrayList<>();
        for (int i = 0; i < logisticsMessage.size(); i++) {
            ExpressInfoVo expressInfoVo = new ExpressInfoVo();
            expressInfoVo.setId(logisticsMessage.get(i).getId().toString());
            expressInfoVo.setTime(cn.hutool.core.date.DateUtil.formatLocalDateTime(logisticsMessage.get(i).getCreatedTime()));
            expressInfoVo.setTitle(concatTitle(logisticsMessage.get(i).getLgType(), logisticsMessage.get(i).getType(), logisticsMessage.get(i).getBusiStat()));
            //第三方物流
            if (isThird) {
                expressInfoVo.setDesc("已交付第三方物流:" + lgThirdLogisRecord.getThirdLogisName() + "  单号为:" + lgThirdLogisRecord.getThirdOrderCode());
            } else {
                expressInfoVo.setDesc(concatDesc(logisticsMessage.get(i).getLgType(), logisticsMessage.get(i).getType(), logisticsMessage.get(i).getBusiStat(),
                        logisticsMessage.get(i).getUserName(), logisticsMessage.get(i).getPhone()));
            }
            expressList.add(expressInfoVo);
            //如果自提是配货完成，额外增加已自提
            if (StringUtils.isNotBlank(additionalTitle(logisticsMessage.get(i).getLgType(), logisticsMessage.get(i).getType(), logisticsMessage.get(i).getBusiStat()))) {
                ExpressInfoVo lastExpressInfoVo = new ExpressInfoVo();
                lastExpressInfoVo.setTitle(additionalTitle(logisticsMessage.get(i).getLgType(), logisticsMessage.get(i).getType(), logisticsMessage.get(i).getBusiStat()));
                lastExpressInfoVo.setDesc(additionalDESC(logisticsMessage.get(i).getLgType(), logisticsMessage.get(i).getType(), logisticsMessage.get(i).getBusiStat()));
                expressList.add(lastExpressInfoVo);
            }
        }
        expressVo.setExpressInfoList(expressList);
        return expressVo;
    }

    public String additionalTitle(Integer lgType, Integer type, Integer busiStat) {
        switch (lgType) {
            case 8:
                switch (type) {
                    case 1:
                    case 8:
                        switch (busiStat) {
                            case 2:
                                return "已自提";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            default:
                return "";
        }
    }

    public String additionalDESC(Integer lgType, Integer type, Integer busiStat) {
        switch (lgType) {
            case 8:
                switch (type) {
                    case 1:
                    case 8:
                        switch (busiStat) {
                            case 2:
                                return "已自提成功";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            default:
                return "";
        }
    }

    public String concatTitle(Integer lgType, Integer type, Integer busiStat) {
        switch (lgType) {
            case 1:
                switch (type) {
                    case 1:
                        switch (busiStat) {
                            case 1:
                                return "配货中";
                            case 2:
                                return "配货完成";
                            default:
                                return "";
                        }
                    case 2:
                        switch (busiStat) {
                            case 1:
                                return "配送中";
                            case 2:
                                return "配送完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
//            case 2:
//                switch (type){
//                    case 3:
//                        switch (busiStat){
//                            case 1:
//                                return "维护中";
//                            case 2:
//                                return "维护完成";
//                            default:
//                                return "";
//                        }
//                    default:
//                        return "";
//                }
            case 3:
                switch (type) {
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "归还中";
                            case 2:
                                return "归还完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 4:
                switch (type) {
                    case 1:
                        switch (busiStat) {
                            case 1:
                                return "配货中";
                            case 2:
                                return "配货完成";
                            default:
                                return "";
                        }
                    case 2:
                        switch (busiStat) {
                            case 1:
                                return "配送中";
                            case 2:
                                return "配送完成";
                            default:
                                return "";
                        }
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "退货中";
                            case 2:
                                return "退货完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 5:
                switch (type) {
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "退货中";
                            case 2:
                                return "退货完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 8:
                switch (type) {
                    case 1:
                    case 8:
                        switch (busiStat) {
                            case 1:
                                return "配货中";
                            case 2:
                                return "配货完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            default:
                return "";
        }

    }

    public String concatDesc(Integer lgType, Integer type, Integer busiStat, String userName, String phone) {


        switch (lgType) {
            case 1:
                switch (type) {
                    case 1:
                        switch (busiStat) {
                            case 1:
                                return "正在配货中。。。";
                            case 2:
                                return "配货完成";
                            default:
                                return "";
                        }
                    case 2:
                        switch (busiStat) {
                            case 1:
                                return "正在配送中。。。配送员：" + userName + "   " + phone;
                            case 2:
                                return "配送完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
//            case 2:
//                switch (type){
//                    case 3:
//                        switch (busiStat){
//                            case 1:
//                                return "维护中";
//                            case 2:
//                                return "维护完成";
//                            default:
//                                return "";
//                        }
//                    default:
//                        return "";
//                }
            case 3:
                switch (type) {
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "归还中";
                            case 2:
                                return "归还完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 4:
                switch (type) {
                    case 1:
                        switch (busiStat) {
                            case 1:
                                return "正在配货中。。。";
                            case 2:
                                return "配货完成";
                            default:
                                return "";
                        }
                    case 2:
                        switch (busiStat) {
                            case 1:
                                return "正在配送中。。。配送员：" + userName + "   " + phone;
                            case 2:
                                return "配送完成";
                            default:
                                return "";
                        }
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "退货中";
                            case 2:
                                return "退货完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 5:
                switch (type) {
                    case 4:
                        switch (busiStat) {
                            case 1:
                                return "退货中";
                            case 2:
                                return "退货完成";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            case 8:
                switch (type) {
                    case 1:
                    case 8:
                        switch (busiStat) {
                            case 1:
                                return "正在配货中。。。";
                            case 2:
                                return "已配货完成，等待用户自提。。。";
                            default:
                                return "";
                        }
                    default:
                        return "";
                }
            default:
                return "";
        }
    }

    /**
     * 根据子订单id获取对应的物流id
     *
     * @param bigOrderSn
     * @param childOrderId
     * @return
     */
    public List<Long> matchOrderAndLogistics(String bigOrderSn, Integer childOrderId) {
        List<Long> baseInfoIds = new ArrayList<>();
        AgedmallLgBaseInfoExample baseInfoExample = new AgedmallLgBaseInfoExample();
        baseInfoExample.or().andOrderCodeEqualTo(bigOrderSn);
        List<AgedmallLgBaseInfo> agedmallLgBaseInfos = agedmallLgBaseInfoMapper.selectByExampleWithBLOBs(baseInfoExample);
        for (int i = 0; i < agedmallLgBaseInfos.size(); i++) {
            AgedmallLgBaseInfo baseInfo = agedmallLgBaseInfos.get(i);
            List<Integer> orderGoodsId = logisticBusiBaseServiceImpl.getorderGoodsIds(baseInfo.getLgContent());
            LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsId.get(0));
            if (orderGoods.getChildOrderId().intValue() == childOrderId.intValue()) {
                baseInfoIds.add(baseInfo.getId());
            }
        }
        return baseInfoIds;
    }

    public BaseResult queryShipChannel(Integer userId, String expressId) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        Map<String, String> expressName = new HashMap<>();
        // todo 物流查询
        expressName.put("expressName", "顺丰");

        return RespUtil.success(expressName);
    }

    public BaseResult orderWarning(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        OrderHandleOption orderHandleOption = OrderUtil.buildItem(orderItem);
        if (!orderHandleOption.isRemind()) {
            throw new BizException("订单不能提醒发货");
        }
        // TODO 先保存通知 具体业务还未规划完成
        AgedmallReplenishNotice notice = new AgedmallReplenishNotice();
        notice.setType(ReplenishNoticeConstant.TYPE_ORDER);
        notice.setOrderId(orderItem.getId());
        notice.setTitle("订单提醒发货");
        notice.setContent("订单提醒发货");
        agedmallReplenishNoticeService.add(notice);

        return RespUtil.success();
    }

    public BaseResult returnMethod(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        AgedmallStore store = agedmallStoreService.findStoreById(orderItem.getStoreId());

        ReturnMethodVo returnMethodVo = new ReturnMethodVo();
        returnMethodVo.setProvince(store.getProvinceName());
        returnMethodVo.setCity(store.getCityName());

        List<ReturnSubOrderGoodsVo> subOrderGoodsList = litemallOrderService.getSubOrderListByBigOrderId(userId, bigOrder.getId(), orderItem.getId());
        List<ReturnSubOrderVo> subOrderList = subOrderGoodsList.stream()
                .map(p -> {
                    ReturnSubOrderVo returnSubOrderVo = new ReturnSubOrderVo();
                    returnSubOrderVo.setSubOrderId(p.getOrderSn());
                    returnSubOrderVo.setGoodsBase(goodsManager.getGoodsBase(p));
                    return returnSubOrderVo;
                }).collect(Collectors.toList());
        returnMethodVo.setSubOrderList(subOrderList);

        if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
            LitemallOrderGoodsExample orderGoodsExample=new LitemallOrderGoodsExample();
            orderGoodsExample.createCriteria().andChildOrderIdEqualTo(orderItem.getId().longValue());
            List<LitemallOrderGoods> orderGoodsList = litemallOrderGoodsMapper.selectByExample(orderGoodsExample);
            JSONObject jsonObject = JSON.parseObject(orderItem.getDeliveryChoose());
            String type = (String) jsonObject.get("type");
            if (type.equals("subHospitalSelf")) {
                HospitalBaseReturnDto baseReturnDto=new HospitalBaseReturnDto();
                //导医台
                if(orderGoodsList.get(0).getHospitalSelfLocationId()!=null&&orderGoodsList.get(0).getLocationHpType()==0){
                    baseReturnDto.setTitle("送货到院");
                    baseReturnDto.setDesc("需要您自行将设备送货到医院，归还到医院导医台，无需支付其他费用");
                    returnMethodVo.setHospitalBaseReturn(baseReturnDto);
                }
                else{
                    baseReturnDto.setTitle("送货到院");
                    baseReturnDto.setDesc("需要您自行将设备送货到医院归位桩，无需支付其他费用");
                    returnMethodVo.setHospitalLockReturn(baseReturnDto);
                }
                returnMethodVo.setDoorReturn(0);
            }
            else{
                //根据是否能自提判断是否能送货上门
                if (store.getSupportSelfDelivery() == 1) {
                    returnMethodVo.setStoreReturn(StoreInfoVo.getInstance(store));
                }
                //自行寄回
//                returnMethodVo.setSelfReturn(StoreInfoVo.getInstance(store));
                //上门取件
                returnMethodVo.setDoorReturn(1);
            }
        }
        else{
            //根据是否能自提判断是否能送货上门
            if (store.getSupportSelfDelivery() == 1) {
                returnMethodVo.setStoreReturn(StoreInfoVo.getInstance(store));
            }
            //自行寄回
//            returnMethodVo.setSelfReturn(StoreInfoVo.getInstance(store));
            //上门取件
            returnMethodVo.setDoorReturn(1);
        }


        return RespUtil.success(returnMethodVo);
    }


    public BaseResult checkUpdoor(CheckUpdoorVo checkUpdoorVo, Integer userId) {
        List<String> subOrderSn = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        checkUpdoorVo.getSubOrderList().forEach(subOrder -> subOrderSn.add(subOrder.getSubOrderId()));
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, checkUpdoorVo.getBigOrderId());
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        List<LitemallOrderItem> order = litemallOrderService.findOrderItemListByCodes(subOrderSn);
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        List<Integer> subOrderIdList = new ArrayList<>();
        order.forEach(o -> subOrderIdList.add(o.getId()));
        BigDecimal price = new BigDecimal(0);
        AgedmallStore store = agedmallStoreMapper.selectByPrimaryKey(order.get(0).getStoreId().longValue());
        List<PickUpPriceDto> pickUpPriceAndGoodsPrice = appOrderMapper.getPickUpPriceAndGoodsPrice(subOrderIdList);
        for (int i = 0; i < pickUpPriceAndGoodsPrice.size(); i++) {
            StoreGoodsVo storeGoods = agedmallStoreGoodsService.getStoreGoodsById(pickUpPriceAndGoodsPrice.get(i).getStoreGoodsId());
            BigDecimal feight = BigDecimal.ZERO;
            if (pickUpPriceAndGoodsPrice.get(i).getStockType() == 3) {
                LitemallRegionExample regionExample = new LitemallRegionExample();
                regionExample.createCriteria().andTypeEqualTo((byte) 1).andNameEqualTo(checkUpdoorVo.getAddress().getProvince());
                LitemallRegion litemallRegions = litemallRegionMapper.selectOneByExample(regionExample);
                feight = orderCalcService.getCloudFeight(storeGoods, litemallRegions.getCode(), pickUpPriceAndGoodsPrice.get(i).getCloudStockId(), true);
            } else {
                feight = orderCalcService.getFeight(storeGoods, store, checkUpdoorVo.getAddress().getLng(), checkUpdoorVo.getAddress().getLat(), true);
            }

            if (feight.equals(new BigDecimal(-1))) {
                map.put("isValid", 0);
                return RespUtil.success(map);
            }
            if (pickUpPriceAndGoodsPrice.get(i).getPickFreight().equals(0)) {
                price = price.add(feight);
            } else if (pickUpPriceAndGoodsPrice.get(i).getPickFreight().equals(2)
                    && pickUpPriceAndGoodsPrice.get(i).getPickFreightCondition().
                    compareTo(pickUpPriceAndGoodsPrice.get(i).getPrice().multiply(new BigDecimal(pickUpPriceAndGoodsPrice.get(i).getNumber()))) > 0
            ) {
                price = price.add(feight);
            }
        }

        String today = cn.hutool.core.date.DateUtil.today();
        long todayQualified = cn.hutool.core.date.DateUtil.parse(today + " 11:00:00").getTime();
        long nowTime = System.currentTimeMillis();

        map.put("isValid", 1);
        map.put("timeInfo", todayQualified >= nowTime ? "11点前申请，预计今天上门取货" : "11点后申请，预计明天上门取货");
        map.put("price", price);
        return RespUtil.success(map);
    }


    /**
     * 单个取回费用计算
     *
     * @return
     */
    public BigDecimal calculatePickUpPrice() {
        BigDecimal price = new BigDecimal(0);

        return price;
    }

    @Transactional
    public BaseResult returnSelfExpress(Integer userId, ReturnSelfExpressForm returnSelfExpressForm) throws CheckException {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, returnSelfExpressForm.getBigOrderId());
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        if (StringUtils.isEmpty(returnSelfExpressForm.getSubOrderIds())) {
            return RespUtil.badArgumentValue();
        }

        List<String> subOrderSn = Arrays.asList(returnSelfExpressForm.getSubOrderIds().split(","));
        List<LitemallOrderItem> subOrderList = litemallOrderService.findOrderItemListByCodes(subOrderSn);
        for (LitemallOrderItem orderItem : subOrderList) {
            OrderHandleOption orderHandleOption = OrderUtil.buildItem(orderItem);
            if (!orderHandleOption.isReback()) {
                throw new BizException("订单不能归还");
            }
            litemallOrderService.updateChildOrderStatus(orderItem.getChildOrderCode(), OrderUtil.STATUS_RETURN_SELF);
        }
        String sunOrderIds = subOrderList.stream().map(p -> p.getId() + "").collect(Collectors.joining(","));

        AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord = new AgedmallLeaseGoodsReturnRecord();
        agedmallLeaseGoodsReturnRecord.setGetGoodsStyle(ReturnGoodsRecordConstant.GET_GOODS_STYLE_SELF_EXPRESS);
        agedmallLeaseGoodsReturnRecord.setBigOrderId(bigOrder.getId() + "");
        agedmallLeaseGoodsReturnRecord.setSubOrderIds(sunOrderIds);
        LogisticsInfo logisticsInfo = returnSelfExpressForm;
        if (CollectionUtils.isNotEmpty(logisticsInfo.getImages())) {
            logisticsInfo.setImages(logisticsInfo.getImages());
        }
        agedmallLeaseGoodsReturnRecord.setLogisticsInfo(JSONObject.toJSONString(logisticsInfo));
        agedmallLeaseGoodsReturnRecordService.add(agedmallLeaseGoodsReturnRecord);
        for (LitemallOrderItem order : subOrderList) {
            // 添加物流节点
            logisticBusiBaseServiceImpl.startReturnGoodsEvent(bigOrder.getOrderSn(), order.getId()
                    , returnSelfExpressForm.getExpressId(), returnSelfExpressForm.getExpressName());
        }
        return RespUtil.success();
    }

    @Transactional
    public BaseResult returnUpdoor(Integer userId, ReturnUpdoorForm returnUpdoorForm) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, returnUpdoorForm.getBigOrderId());
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        if (CollectionUtils.isEmpty(returnUpdoorForm.getSubOrderList())) {
            return RespUtil.badArgumentValue();
        }
        //子订单号集合
        List<String> subOrderSn = returnUpdoorForm.getSubOrderList().stream().map(p -> p.getSubOrderId()).collect(Collectors.toList());
        //获取所有的子订单集合
        List<LitemallOrderItem> subOrderList = litemallOrderService.findOrderItemListByCodes(subOrderSn);
        for (LitemallOrderItem orderItem : subOrderList) {
            OrderHandleOption orderHandleOption = OrderUtil.buildItem(orderItem);
            if (!orderHandleOption.isReback()) {
                throw new BizException("订单不能归还");
            }
            //归还订单
            litemallOrderService.updateChildOrderStatus(orderItem.getChildOrderCode(), OrderUtil.STATUS_RETURN);
        }
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.getOrderGoodsListByChildOrderCode(subOrderList.get(0).getChildOrderCode());
        LitemallOrderGoods orderGoods = orderGoodsList.stream().filter(p -> OrderGoodsConstant.TYPE_GOODS.equals(p.getType())).findFirst().get();
        String subOrderIds = subOrderList.stream().map(p -> p.getId() + "").collect(Collectors.joining(","));

        AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord = new AgedmallLeaseGoodsReturnRecord();
        agedmallLeaseGoodsReturnRecord.setGetGoodsStyle(ReturnGoodsRecordConstant.GET_GOODS_STYLE_PICK_UP);
        agedmallLeaseGoodsReturnRecord.setBigOrderId(bigOrder.getId() + "");
        agedmallLeaseGoodsReturnRecord.setSubOrderIds(subOrderIds);
        agedmallLeaseGoodsReturnRecord.setUserAddressInfo(JSONObject.toJSONString(returnUpdoorForm.getAddress()));
        String today = cn.hutool.core.date.DateUtil.today();
        long todayQualified = cn.hutool.core.date.DateUtil.parse(today + " 11:00:00").getTime();
        long nowTime = System.currentTimeMillis();
        if (nowTime < todayQualified) {
            agedmallLeaseGoodsReturnRecord.setDate(LocalDateTime.now());
        } else {
            agedmallLeaseGoodsReturnRecord.setDate(cn.hutool.core.date.DateUtil.tomorrow().toTimestamp().toLocalDateTime());
        }
        agedmallLeaseGoodsReturnRecord.setTime("23:59");
        BigDecimal updoorPrice = BigDecimal.ZERO;
        AgedmallLeaseSubbackConf agedmallLeaseSubbackConf = agedmallLeaseSubbackConfService.findByStoreId(orderGoods.getStoreId());
        if (null != agedmallLeaseSubbackConf) {
            List<DoorReturnReservationTimesVo> doorReturnReservationTimesVo = JSONObject.parseArray(agedmallLeaseSubbackConf.getDayTimes(), DoorReturnReservationTimesVo.class);
            for (DoorReturnReservationTimesVo returnReservationTimesVo : doorReturnReservationTimesVo) {
                String time = returnReservationTimesVo.getStime() + "-" + returnReservationTimesVo.getEtime();
                if (time.equals(returnUpdoorForm.getTime())) {
                    updoorPrice = returnReservationTimesVo.getPrice();
                }
            }
        }
        agedmallLeaseGoodsReturnRecord.setUpdoorPrice(updoorPrice);
        agedmallLeaseGoodsReturnRecordService.add(agedmallLeaseGoodsReturnRecord);
        LogisticsBackUserAddressData userBackAddress = new LogisticsBackUserAddressData();
        BeanUtil.copyProperties(returnUpdoorForm.getAddress(), userBackAddress);

        List<AgedmallLgBaseInfo> baseInfoList = logisticBusiBaseServiceImpl.createLgBaseInfo(bigOrder, subOrderList, userBackAddress, LgBaseInfoLgType.GIVEBACK.getCode(), LgBaseInfoStatConstant.RETURNING);
        for (AgedmallLgBaseInfo baseInfo : baseInfoList) {
            AgedmallStoreGoods storeGoods=agedmallStoreGoodsMapper.selectByPrimaryKey(orderGoods.getStoreGoodsId().longValue());

            //判断取回是否走顺丰物流取回
            if(storeGoods.getPickUpType()==0){
                logger.info("取回开始走第三方物流:{},{}",storeGoods.getId(),baseInfo.getId());
                List<Integer> missionList = logisticBusiBaseServiceImpl. createMissionBackstage(null, baseInfo.getId().intValue(), LogisticsMissionTypeEnum.RETURN.getCode());
                try {
                    logisticBusiBaseServiceImpl.thirdLogisEvent(missionList.get(0), "","顺丰", 1);
                } catch (CheckException e) {
                  logger.error("取回第三方物流创建失败:{}",baseInfo.getId());
                }
            }
            else{
            logisticBusiBaseServiceImpl.userCreateOrderEvent(null, baseInfo.getId().intValue(), LogisticsMissionTypeEnum.RETURN.getCode());
            }

        }

        return RespUtil.success();
    }

    @Transactional
    public BaseResult cancelReturn(Integer userId, String bigOrderCode, String childOrderCode) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderCode);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        LitemallOrderItem orderItem = litemallOrderService.findItemBySn(userId, bigOrderCode, childOrderCode);
        if (null == orderItem) {
            return RespUtil.badArgumentValue();
        }
        AgedmallLeaseGoodsReturnRecord agedmallLeaseGoodsReturnRecord = agedmallLeaseGoodsReturnRecordService.findByOrderIdAndSubOrderId(bigOrder.getId() + "", orderItem.getId() + "");
        if (null != agedmallLeaseGoodsReturnRecord) {
            String subOrderIds = agedmallLeaseGoodsReturnRecord.getSubOrderIds();
            List<String> subOrderIdList = Arrays.stream(subOrderIds.split(",")).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(subOrderIdList)) {
                if (subOrderIdList.size() == 1) {
                    agedmallLeaseGoodsReturnRecordService.delete(agedmallLeaseGoodsReturnRecord);
                } else {
                    subOrderIdList.remove(childOrderCode);
                    String newSubOrderIds = subOrderIdList.stream().collect(Collectors.joining(","));
                    agedmallLeaseGoodsReturnRecord.setSubOrderIds(newSubOrderIds);
                    agedmallLeaseGoodsReturnRecordService.update(agedmallLeaseGoodsReturnRecord);
                }
            }
        }

        litemallOrderService.updateChildOrderStatus(childOrderCode, OrderUtil.STATUS_LEASE_CONFIRM);
        //物流关闭
        logisticBusiBaseServiceImpl.cancelReturn(bigOrder.getOrderSn(), orderItem.getChildOrderCode());
        return RespUtil.success();
    }

    public BaseResult queryOrderStatus(Integer userId, String bigOrderId, Integer queryType) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder bigOrder = litemallOrderService.findBySn(userId, bigOrderId);
        if (null == bigOrder) {
            return RespUtil.badArgumentValue();
        }
        short status = bigOrder.getOrderStatus();
        if (OrderUtil.STATUS_CREATE.equals(bigOrder.getOrderStatus())) {
            if (queryType == 0) {
                status = wxQueryOrder(bigOrder);
            } else {
                status = wxQueryPayScoreOrder(bigOrder);
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("bigOrderId", bigOrder.getOrderSn());
        map.put("payStatus", OrderUtil.showType(status));
        return RespUtil.success(map);
    }

    @Transactional
    public BaseResult orderSubmit(Integer userId, OrderSubmitForm orderSubmitForm, String spbillCreateIp) throws CheckException {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallAddress litemallAddress = litemallAddressService.query(userId, orderSubmitForm.getAddressId());
        if (null == litemallAddress) {
            return RespUtil.badArgumentValue();
        }



        String bigOrderCode = getOrderSn();

        // 商品价格 + 在线服务价格
        LitemallOrder bigOrder = saveOrder(userId, litemallAddress, bigOrderCode, orderSubmitForm.getIsCredit(), orderSubmitForm.getAutoUseDeduct());
        // 商品价格
        BigDecimal bigOrderGoodsPrice = BigDecimal.ZERO;
        // 运费
        BigDecimal bigOrderDeliveryPrice = BigDecimal.ZERO;

        List<TempSubOrderForm> tempSubOrderList = orderSubmitForm.getTempSubOrderList();
        int orderNo = 1;
        List<String> rfids = new ArrayList<>();
        // key:服务商品编号，value:orderGoodsId
        Map<Integer, Integer> serviceGoodsMap = new HashMap<>();
        // key:服务商品编号，value:子订单id
        Map<Integer, Integer> serviceOrderMap = new HashMap<>();
        for (TempSubOrderForm tempSubOrderForm : tempSubOrderList) {
            List<TempSubOrderGoods> goodsList = tempSubOrderForm.getGoodsList();
            GoodsBaseData goodsBase = goodsList.get(0).getGoodsBase();
            StoreGoodsVo storeGoodsVo = agedmallStoreGoodsService.getStoreGoodsById(goodsBase.getId());
            AgedmallStore store = agedmallStoreService.findStoreById(storeGoodsVo.getStoreId());
//            LitemallGoods litemallGoods = litemallGoodsService.findById(storeGoodsVo.getId());
            TempSubOrderParam inputParams = tempSubOrderForm.getInputParams();
            // 保存子订单
            String subOrderNo = bigOrder.getOrderSn() + "-" + orderNo++;
            //单独存储子订单记录，后续业务从主订单中拆离出去
            LitemallOrderItem orderItem = saveOrderItem(bigOrderCode, userId, subOrderNo, null, null, bigOrder.getId(), goodsBase.getType(), storeGoodsVo.getStoreId());
            int childOrderId = orderItem.getId();
            int bigOrderId = bigOrder.getId();

            BigDecimal subOrderGoodsTotalPrice = BigDecimal.ZERO;
            // 商品列表
            List<StoreGoodsVo> storeGoodsVos = new ArrayList<>();
            // 保存商品
            for (TempSubOrderGoods tempSubOrderGoods : goodsList) {
                SkuInfo skuInfo = tempSubOrderGoods.getSkuInfo();
                SelectedSpecInfo selectedGoodsSpec = skuInfo.getSelectedGoodsSpec();
//                LitemallGoodsProduct product = productService.findById(selectedGoodsSpec.getId());
                StoreGoodsVo storeGoods = agedmallStoreGoodsService.getStoreGoodsById(goodsBase.getId());
                StoreGoodsProductVo product = agedmallStoreGoodsService.getStoreGoodsProduct(storeGoods.getStoreId(), storeGoods.getId(), selectedGoodsSpec.getId());
                storeGoods.setStock(selectedGoodsSpec.getStock());
                storeGoods.setCloudStockId(selectedGoodsSpec.getCloudStockId());
                storeGoodsVos.add(storeGoods);
//                LitemallGoods goods = litemallGoodsService.findById(storeGoods.getId());
                TempSubOrderParamDelivery delivery = inputParams.getDelivery();
                LitemallOrderGoods orderGoods = saveOrderGoods(store, storeGoods, product, selectedGoodsSpec, bigOrderId, tempSubOrderGoods, childOrderId, bigOrderCode, subOrderNo, delivery);

                serviceGoodsMap.put(tempSubOrderGoods.getServiceGoodsNo(), orderGoods.getId());
                serviceOrderMap.put(tempSubOrderGoods.getServiceGoodsNo(), childOrderId);
                if (StringUtils.isNotEmpty(orderGoods.getRfid())) {
                    rfids.add(orderGoods.getRfid());
                }
                GoodsVipSalesDto selectProductVipSale = cartManager.getSelectProductVipSale(product.
                        getVipJson(),userId,orderGoods.getNumber().intValue(),storeGoods.getVipPriceFlag());
                skuInfo.setSelectedSkuVipSale(selectProductVipSale);
                BigDecimal salePrice=ObjectUtil.isNotNull(selectProductVipSale)&&selectProductVipSale.getPrice()!=null?selectProductVipSale.getPrice():orderGoods.getPrice();
                subOrderGoodsTotalPrice = subOrderGoodsTotalPrice.add(salePrice.multiply(new BigDecimal(orderGoods.getNumber())));
                // 保存配件
                List<SelectedSpecInfo> selectedCustomSpec = skuInfo.getSelectedCustomSpec();
                for (SelectedSpecInfo selectedSpecInfo : selectedCustomSpec) {
                    if (selectedSpecInfo.getIsInvalid().equals(0)) {
                        StoreGoodsVo storeGoodsvo = agedmallStoreGoodsService.getStoreGoodsById(selectedSpecInfo.getId());
                        StoreGoodsProductVo partProduct = agedmallStoreGoodsService.getStoreGoodsProduct(storeGoodsvo.getStoreId(), storeGoodsvo.getId(), selectedSpecInfo.getSkuId());
                        storeGoodsvo.setStock(selectedSpecInfo.getStock());
//                    storeGoodsVos.add(storeGoodsvo);
                        LitemallOrderGoods parts = saveOrderParts(store, storeGoods, partProduct, storeGoodsvo, selectedSpecInfo, bigOrderId, orderGoods.getId(), tempSubOrderGoods.getSaleUserId(), childOrderId, bigOrderCode, subOrderNo);
                        AgedmallGoodsParts goodsParts = agedmallGoodsPartsService.getByGoodsIdAndCustGoodsId(storeGoods.getId(), storeGoodsvo.getId());
                        // 售卖商品 或是配件先付的租赁商品 订单价格加上配件价格
                        if (GoodsConstant.GOODS_TYPE_SALE.equals(storeGoods.getGoodsType())
                                || (null != parts && goodsParts.getPayOrder().equals(0))) {
                            subOrderGoodsTotalPrice = subOrderGoodsTotalPrice.add(parts.getPrice().multiply(new BigDecimal(parts.getNumber())));
                        }
                    }
                }

                // 保存服务
                List<SelectedSpecInfo> selectedExtendSpec = skuInfo.getSelectedExtendSpec();
                for (SelectedSpecInfo selectedSpecInfo : selectedExtendSpec) {
                    LitemallOrderGoods service = saveOrderService(selectedSpecInfo, bigOrderId, (long) childOrderId, subOrderNo, orderGoods.getId(), tempSubOrderGoods.getSaleUserId());
                    subOrderGoodsTotalPrice = subOrderGoodsTotalPrice.add(service.getPrice().multiply(new BigDecimal(service.getNumber())));
                }
                //分成信息设置
                List<ChannelGoodsBindDto> channelGoodsBindDto = null;
                if (!tempSubOrderForm.getChannelGoodsBind().isEmpty()) {
                    channelGoodsBindDto = tempSubOrderForm.getChannelGoodsBind();
                } else if (orderSubmitForm.getGroupIds() != null) {
                    channelGoodsBindDto = this.getCartPromoteInfo(orderSubmitForm.getGroupIds());
                }
                if (channelGoodsBindDto != null && channelGoodsBindDto.size() >0) {
                    this.insertPromoteSettleMent(orderItem, orderGoods, userId, channelGoodsBindDto);
                }
            }

            // 删除购物车
            if (StringUtils.isNotEmpty(orderSubmitForm.getGroupIds())) {
                List<String> goodsGroupIdList = Arrays.stream(orderSubmitForm.getGroupIds().split(",")).collect(Collectors.toList());
                litemallCartService.removeByGoodsGroupIdList(userId, goodsGroupIdList);
            }

            // 配送方式
            BigDecimal deliveryPrice = BigDecimal.ZERO;
            if (null != inputParams) {
                TempSubOrderParamDelivery delivery = inputParams.getDelivery();
                FeightFeeResult feightFeeResult = orderCalcService.calFeightFee(storeGoodsVos, litemallAddress, store, delivery);
                deliveryPrice = feightFeeResult.getDeliveryPrice();

                //更新拆离出的子订单信息
                orderItem.setDeliverySn(feightFeeResult.getDeliverySn());
                orderItem.setDeliveryChoose(feightFeeResult.getDeliveryChoose());
                orderItem.setExtractShop(feightFeeResult.getExtractShop());
                orderItem.setIsHospital(feightFeeResult.getIsHospital());
                orderItem.setHospitalId(feightFeeResult.getHospitalId());
                orderItem.setHospitalName(feightFeeResult.getHospitalName());
            }

            StoreGoodsVo storeGoods = storeGoodsVos.get(0);
            //单个租赁商品 运费是先付还是后付,后付费 运维为0
            boolean isAfterPay = 1 == storeGoodsVos.size() &&
                    GoodsConstant.GOODS_TYPE_LEASE.equals(storeGoods.getGoodsType()) &&
                    storeGoods.getPayOrder().equals(GoodsPayStyleEnum.AFTER_PAY.getPayStyle());

            //订单配送费用
            BigDecimal subOrderDeliverPrice = isAfterPay ? BigDecimal.ZERO : deliveryPrice;
            //子订单总费用
            BigDecimal subOrderTotalPrice = subOrderGoodsTotalPrice.add(subOrderDeliverPrice);
            BigDecimal checkPrice = tempSubOrderForm.getCheckPrice();
            //检查费用是否一致
            if (checkPrice.compareTo(subOrderTotalPrice) != 0) {
                logger.error("下单失败 单个租赁商品 上传价格与计算价格不匹配 {},{},{},{},{}", userId, checkPrice, subOrderTotalPrice, subOrderGoodsTotalPrice, subOrderDeliverPrice);
                throw new BizException("下单失败");
            }
            if (isAfterPay) {
                //将后付费的运维记录到 费用扩展表中，待最后结算时取出进行结算
                AgedmallOrderFeeExt feeExt = new AgedmallOrderFeeExt();
                feeExt.setFee(deliveryPrice);
                feeExt.setOrderCode(bigOrderCode);
                feeExt.setFeeName(OrderFeeExtNameEnum.AFTER_PAY_DELIVER_FEE.getExtName());
                feeExt.setItemOrderCode(subOrderNo);
                agedmallFreightTemplateService.addOrderExtFeeData(feeExt);
            }

            bigOrderGoodsPrice = bigOrderGoodsPrice.add(subOrderGoodsTotalPrice);
            bigOrderDeliveryPrice = bigOrderDeliveryPrice.add(subOrderDeliverPrice);

            //拆离的子订单运费及订单费用设置更新
            orderItem.setFreightPrice(subOrderDeliverPrice);
            orderItem.setOrderPrice(subOrderGoodsTotalPrice);
            //存在优惠券抵扣金等的选优扣除后算出实际支付金额
            BigDecimal actualPayPrice = subOrderTotalPrice;
            orderItem.setActualPrice(actualPayPrice);
            litemallOrderService.updateItem(orderItem);
            //分成修改订单价格
            //this.updatePromoteSettleMentPayMoney(orderItem);
        }

        if (null != orderSubmitForm.getTempServiceOrderList()) {
            String city = litemallAddress.getCity();
            for (TempServiceOrderForm tempServiceOrderForm : orderSubmitForm.getTempServiceOrderList()) {
                TempSubOrderGoods goodsInfo = tempServiceOrderForm.getGoodsInfo();
                ServiceProductVo product = litemallGoodsProductService.findServiceById(goodsInfo.getSkuInfo().getSelectedGoodsSpec().getId(), city);

                AgedmallGoodsOnlineServiceExample goodsOnlineServiceExample = new AgedmallGoodsOnlineServiceExample();
                goodsOnlineServiceExample.or().andDeletedEqualTo(false)
                        .andGoodsIdEqualTo(goodsInfo.getGoodsId())
                        .andOnlineSerivceProductIdEqualTo(goodsInfo.getGoodsBase().getId());
                AgedmallGoodsOnlineService goodsOnlineService = agedmallGoodsOnlineServiceMapper.selectOneByExample(goodsOnlineServiceExample);
                AgedmallServiceOrder serviceOrder = new AgedmallServiceOrder();
                serviceOrder.setOrderId(bigOrder.getId().longValue());
                serviceOrder.setOrderSn(getOrderSn());

                AgedmallOnlineCityExample cityExample = new AgedmallOnlineCityExample();
                cityExample.createCriteria().andDeletedEqualTo(false)
                        .andOnlineServerIdEqualTo(Long.valueOf(goodsInfo.getGoodsBase().getId()))
                        .andCityEqualTo(city);
                AgedmallOnlineCity agedmallOnlineCity = agedmallOnlineCityMapper.selectOneByExample(cityExample);
                serviceOrder.setOnlineCitySerivceId(null != agedmallOnlineCity ? agedmallOnlineCity.getId().longValue() : null);
                serviceOrder.setStat(ServiceOrderConstant.STATUS_INIT);
                serviceOrder.setServiceId(goodsInfo.getGoodsBase().getId());
                serviceOrder.setServiceProductId(goodsInfo.getSkuInfo().getSelectedGoodsSpec().getId());
                serviceOrder.setServicePrice(product.getCityProductPrice());
                serviceOrder.setRemark(null != tempServiceOrderForm.getInputParams() ? tempServiceOrderForm.getInputParams().getRemark() : null);
                serviceOrder.setAddTime(LocalDateTime.now());
                serviceOrder.setDeleted(false);
                serviceOrder.setGoodsId(goodsInfo.getGoodsId());
                serviceOrder.setStoreGoodsId(goodsInfo.getStoreGoodsId());
                serviceOrder.setOrderPay(goodsOnlineService.getPayOrder());
                serviceOrder.setOrderGoodsId(serviceGoodsMap.get(goodsInfo.getServiceGoodsNo()));
                serviceOrder.setSubOrderId(serviceOrderMap.get(goodsInfo.getServiceGoodsNo()));
                // 确认页面预约
                TempServiceOrderParam serviceOrderParam = tempServiceOrderForm.getInputParams();
                if (null != serviceOrderParam && null != serviceOrderParam.getIsSub() && serviceOrderParam.getIsSub()) {
                    LocalDate subDate = LocalDate.parse(serviceOrderParam.getSubDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    String[] times = serviceOrderParam.getSubTime().split("~");
                    LocalTime startTime = LocalTime.parse(times[0], DateTimeFormatter.ofPattern("HH:mm"));
                    LocalTime endTime = LocalTime.parse(times[1], DateTimeFormatter.ofPattern("HH:mm"));
                    LocalDateTime start = LocalDateTime.of(subDate, startTime);
                    LocalDateTime end = LocalDateTime.of(subDate, endTime);
                    serviceOrder.setFullAppointTime(start);
                    serviceOrder.setAppointmentTime(subDate.atStartOfDay());
                    serviceOrder.setStartTime(start);
                    serviceOrder.setEndTime(end);
                    serviceOrder.setUserDescribe(serviceOrderParam.getRemark());
                    if (CollectionUtils.isNotEmpty(serviceOrderParam.getImages())) {
                        serviceOrder.setDescribeImgs(JSONObject.toJSONString(serviceOrderParam.getImages()));
                    }
                    serviceOrder.setDepid(serviceOrderParam.getDepId().longValue());
                    serviceOrder.setWechatphone(serviceOrderParam.getWechatPhone());
                    serviceOrder.setHelptext(serviceOrderParam.getHelpText());
                }
                agedmallServiceOrderMapper.insertSelective(serviceOrder);


                //根据商品id查询
                if (goodsOnlineService.getPayOrder() == 0) {//先付
                    if (tempServiceOrderForm.getCheckPrice().compareTo(product.getCityProductPrice()) != 0) {
                        throw new BizException("下单失败");
                    }
                }
                if (goodsOnlineService.getPayOrder() == 1) {//后付(判断传过来的值是否为0)
                    if (tempServiceOrderForm.getCheckPrice().compareTo(BigDecimal.ZERO) != 0) {
                        throw new BizException("下单失败");
                    }
                }
                if (goodsOnlineService.getPayOrder().equals(0)) {
                    bigOrderGoodsPrice = bigOrderGoodsPrice.add(product.getCityProductPrice());
                }
            }
        }

        BigDecimal formCheckPrice = orderSubmitForm.getCheckPrice();
        if (formCheckPrice.compareTo(bigOrderGoodsPrice.add(bigOrderDeliveryPrice)) != 0) {
            logger.error("下单失败 {},{},{},{}", userId, formCheckPrice, bigOrderGoodsPrice, bigOrderDeliveryPrice);
            throw new BizException("下单失败");
        }

        // 更新大订单总价和运费
        updateMainOrderPrice(bigOrder.getId(), bigOrderGoodsPrice, bigOrderDeliveryPrice);

        // 订单支付超期任务
        taskService.addTask(new OrderUnpaidTask(bigOrder.getId()));

        return createWxPayOrder(userId, bigOrder.getOrderSn(), orderSubmitForm.getCode(), orderSubmitForm.getIsCredit(), spbillCreateIp);
    }


    /**
     * 从购物中获取推广信息
     */
    private List<ChannelGoodsBindDto> getCartPromoteInfo(String cartGroupId) {
        List<ChannelGoodsBindDto> channelGoodsBindDtoList = null;
        //到购物车中查询推广信息
        if (cartGroupId != null) {
            String[] cartId = cartGroupId.split(",");
            channelGoodsBindDtoList = new ArrayList<>();
            for (String groupId : cartId) {
                //查询购物车信息
                LitemallCartExample cartExample = new LitemallCartExample();
                cartExample.or().andGoodsGroupIdEqualTo(groupId).andDeletedEqualTo(false);
                LitemallCart litemallCart = litemallCartMapper.selectOneByExample(cartExample);
                if (litemallCart != null && litemallCart.getSaleUserId() != null) {
                    //获取推广信息
                    ChannelGoodsBindDto channelGoodsBindDto = new ChannelGoodsBindDto();
                    channelGoodsBindDto.setGoodsId(litemallCart.getGoodsId().longValue());
                    channelGoodsBindDto.setHosLinkCode(litemallCart.getHosLinkCode());
                    channelGoodsBindDto.setChannel(litemallCart.getChannel());
                    channelGoodsBindDto.setSaleUserId(Integer.parseInt(litemallCart.getSaleUserId()));
                    channelGoodsBindDtoList.add(channelGoodsBindDto);
                }
            }
        }
        return channelGoodsBindDtoList;
    }


    /**
     * 分成价格修改
     *
     * @param orderItem
     */
    private void updatePromoteSettleMentPayMoney(LitemallOrderItem orderItem) {
        //分成修改订单价格
        AgedmallPromoteSettlementExample promoteSettlementExample = new AgedmallPromoteSettlementExample();
        promoteSettlementExample.createCriteria().andItemsIdEqualTo(orderItem.getId());
        AgedmallPromoteSettlement promoteSettlement = new AgedmallPromoteSettlement();
        promoteSettlement.setPayAmount(orderItem.getActualPrice());
        agedmallPromoteSettlementMapper.updateByExampleSelective(promoteSettlement, promoteSettlementExample);
    }


    /**
     * 设置订单结算表
     */
    private void insertPromoteSettleMent(LitemallOrderItem orderItem,
                                         LitemallOrderGoods litemallOrderGoods,
                                         Integer userId,
                                         List<ChannelGoodsBindDto> channelGoodsBindDto) {
        for (ChannelGoodsBindDto clbd : channelGoodsBindDto) {

            //通过代理表id查询用户推广员信息
            AgedmallPromoteAgentInfo litemallUser = agedmallServiceOrderManageMapper.getUserIsDelete(clbd.getSaleUserId());
            if (litemallUser == null || litemallUser.getDeleted()) {
                continue;
            }
            //如果方案不存在
            AgedmallCustomTemplate customTemplate = agedmallUserCustomTemplateMapper.getCustomTemplateInfo(clbd.getSaleUserId());
            if (customTemplate == null) {
                continue;
            }

            //判断商品是否在推广员商品列表中
            String goodsId = customTemplate.getCanCustomGoods();
            //通过门店商品id查询
            AgedmallStoreGoods storeGoods = this.getStoreGoods(clbd.getGoodsId());
            if (customTemplate.getCanCustomGoodsType() == 0 ||
                    customTemplate.getCanCustomGoodsType() == 1) {//全部商品、部分商品
                int goodsIdIndex = goodsId.indexOf(String.valueOf(storeGoods.getGoodsId()));
                if (goodsIdIndex == -1) {
                    continue;
                }
            }
            if (customTemplate.getCanCustomGoodsType() == 2) {//不参与商品
                int goodsIdIndex = goodsId.indexOf(String.valueOf(storeGoods.getGoodsId()));
                if (goodsIdIndex != -1) {//说明存在
                    continue;
                }
            }

            //判断方案是否包含该商品的门店
            String storesId = customTemplate.getCanCustomStore();
            int storesIdIndex = storesId.indexOf(String.valueOf(orderItem.getStoreId()));
            if (storesIdIndex == -1) {
                continue;
            }

            //根据门店商品id查询商品信息
            AgedmallStoreGoods agedmallStoreGoods = agedmallStoreGoodsMapper.selectByPrimaryKey(clbd.getGoodsId());
            if (litemallOrderGoods.getGoodsId() != null &&
                    agedmallStoreGoods.getGoodsId() == litemallOrderGoods.getGoodsId().longValue()) {
                if (orderItem.getChildOrderCode() == litemallOrderGoods.getChildOrderCode()) {
                    //2:表示医院护工 3:表示代理推广
                    if (clbd.getChannel() == 2 || clbd.getChannel() == 3 || clbd.getChannel() == 0) {
                        AgedmallPromoteSettlement promoteSettlement = new AgedmallPromoteSettlement();
                        promoteSettlement.setBigNumber(orderItem.getOrderCode());//大订单号
                        promoteSettlement.setSmallNumber(orderItem.getChildOrderCode());//小订单号
                        promoteSettlement.setStoresId(orderItem.getStoreId());//门店id
                        promoteSettlement.setGoodId(litemallOrderGoods.getGoodsId());//商品id
                        promoteSettlement.setAddTime(LocalDateTime.now());//添加时间
                        promoteSettlement.setSettlementStatus(0L);//结算状态 0:表示否 1:表示是
                        promoteSettlement.setSettlementType(0L);//1表示支付 2:表示退款(暂无)
                        promoteSettlement.setVisitUserId(userId);//访问人，下单用户id
                        if (litemallUser.getShopId() != null) {
                            promoteSettlement.setShopId(litemallUser.getShopId().toString());//店铺id
                        }
                        promoteSettlement.setPromoteId(litemallUser.getId());
                        promoteSettlement.setPromoteType(clbd.getChannel().toString());//推广类型
                        promoteSettlement.setType(litemallOrderGoods.getType());//商品类型
                        promoteSettlement.setItemsId(orderItem.getId());//子订单id
                        promoteSettlement.setBigorderid(litemallOrderGoods.getOrderId());//大订单id
                        promoteSettlement.setPlanId(customTemplate.getId());//推广方案id
                        promoteSettlement.setPayAmount(orderItem.getActualPrice());
                        agedmallPromoteSettlementMapper.insert(promoteSettlement);
                    }
                }

            }
        }
    }


    /**
     * 通过门店id查询门店信息
     *
     * @param id
     * @return
     */
    private AgedmallStoreGoods getStoreGoods(Long id) {
        AgedmallStoreGoods storeGoods = agedmallStoreGoodsMapper.selectByPrimaryKey(id.longValue());
        return storeGoods;
    }


    private BigDecimal getShipFee(Integer goodsId, Double distance) {
        BigDecimal result = BigDecimal.ZERO;
        AgedmallShipChargeRule agedmallShipChargeRule = agedmallShipChargeRuleService.getByGoodsId(goodsId);
        if (null == agedmallShipChargeRule) {
            return result;
        }
        AgedmallShipChargeRuleInfo ruleInfo = JSONObject.parseObject(agedmallShipChargeRule.getChargeRule(), AgedmallShipChargeRuleInfo.class);
        if (null == ruleInfo) {
            return result;
        }

        if (distance > ruleInfo.getMaxDistance()) {
            throw new BizException("超出同城配送范围");
        }
        if (distance <= ruleInfo.getMinDistance()) {
            return ruleInfo.getMinFee();
        }
        result = result.add(ruleInfo.getMinFee());
        for (AgedmallShipChargeRuleConf rule : ruleInfo.getRules()) {
            if (distance >= rule.getBegin()) {
                double max = distance >= rule.getEnd() ? rule.getEnd() : distance;
                double diff = max - rule.getBegin();
                result = result.add(rule.getPrice().multiply(new BigDecimal(diff)));
            }
        }
        return result;
    }

    private LitemallOrder saveOrder(Integer userId, LitemallAddress litemallAddress, String orderSn, Integer isCredit, Integer autoUseDeduct) {
        return saveOrder(userId, litemallAddress, orderSn, isCredit, autoUseDeduct, null, null, null, null);
    }

    private LitemallOrder saveOrder(Integer userId, LitemallAddress litemallAddress, String orderSn, Integer isCredit, Integer autoUseDeduct, Integer parentId, String goodsType, String remark, Integer storeId) {
        LitemallOrder litemallOrder = new LitemallOrder();
        litemallOrder.setStoreId(storeId);
        litemallOrder.setParentId(parentId);
        litemallOrder.setUserId(userId);
        litemallOrder.setOrderSn(orderSn);
        litemallOrder.setOrderStatus(OrderUtil.STATUS_CREATE);
        litemallOrder.setAftersaleStatus(AftersaleConstant.STATUS_INIT);
        litemallOrder.setConsignee(litemallAddress.getName());
        litemallOrder.setMobile(litemallAddress.getTel());
        litemallOrder.setProvince(litemallAddress.getProvince());
        litemallOrder.setCity(litemallAddress.getCity());
        litemallOrder.setCounty(litemallAddress.getCounty());
        litemallOrder.setAddress(litemallAddress.getAddress());
        litemallOrder.setAddressDetail(litemallAddress.getAddressDetail());
        litemallOrder.setLat(litemallAddress.getLat());
        litemallOrder.setLng(litemallAddress.getLng());
        litemallOrder.setGoodsType(goodsType);
        litemallOrder.setMessage(remark);
        litemallOrder.setIsCredit(isCredit);
        litemallOrder.setAutoUseDeduct(autoUseDeduct);

        // 价格统计完再更新进去
        litemallOrder.setGoodsPrice(BigDecimal.ZERO);
        litemallOrder.setFreightPrice(BigDecimal.ZERO);
        litemallOrder.setCouponPrice(BigDecimal.ZERO);
        litemallOrder.setIntegralPrice(BigDecimal.ZERO);
        litemallOrder.setGrouponPrice(BigDecimal.ZERO);
        litemallOrder.setOrderPrice(BigDecimal.ZERO);
        litemallOrder.setActualPrice(BigDecimal.ZERO);

        litemallOrderService.add(litemallOrder);
        return litemallOrder;
    }

    /**
     * 保存子订单信息
     *
     * @param userId
     * @param subOrderCode
     * @param isCredit
     * @param autoUseDeduct
     * @param parentId
     * @param goodsType
     * @param storeId
     * @return
     */
    private LitemallOrderItem saveOrderItem(String bigOrderCode, Integer userId, String subOrderCode, Integer isCredit, Integer autoUseDeduct, Integer parentId, String goodsType, Integer storeId) {
        LitemallOrderItem litemallOrder = new LitemallOrderItem();
        litemallOrder.setStoreId(storeId);
        litemallOrder.setParentId(parentId);
        litemallOrder.setUserId(userId);
        litemallOrder.setOrderCode(bigOrderCode);
        litemallOrder.setChildOrderCode(subOrderCode);
        litemallOrder.setOrderStatus(OrderUtil.STATUS_CREATE);
        litemallOrder.setAftersaleStatus(AftersaleConstant.STATUS_INIT);
        litemallOrder.setGoodsType(goodsType);
        litemallOrder.setIsCredit(isCredit);
        litemallOrder.setAutoUseDeduct(autoUseDeduct);

        // 价格统计完再更新进去
        litemallOrder.setGoodsPrice(BigDecimal.ZERO);
        litemallOrder.setFreightPrice(BigDecimal.ZERO);
        litemallOrder.setCouponPrice(BigDecimal.ZERO);
        litemallOrder.setIntegralPrice(BigDecimal.ZERO);
        litemallOrder.setGrouponPrice(BigDecimal.ZERO);
        litemallOrder.setOrderPrice(BigDecimal.ZERO);
        litemallOrder.setActualPrice(BigDecimal.ZERO);

        litemallOrderService.addItem(litemallOrder);
        return litemallOrder;
    }

    private LitemallOrderGoods saveOrderService(SelectedSpecInfo selectedSpecInfo, Integer orderId, Long childOrderId, String childOrderCode, Integer parentId, Integer saleUserId) {
        LitemallGoodsProduct product = productService.findById(selectedSpecInfo.getId());
        LitemallGoodsSpecification litemallGoodsSpecification = litemallGoodsSpecificationService.findById(selectedSpecInfo.getId());
        AgedmallGoodsService service = agedmallGoodsServiceService.getByProductId(product.getId());
        LitemallGoods goods = litemallGoodsService.findById(product.getGoodsId());
        boolean flag = GoodsConstant.GOODS_TYPE_LEASE.equals(goods.getGoodsType());

        LitemallOrderGoods orderGoods = new LitemallOrderGoods();
        orderGoods.setOrderId(orderId);
        orderGoods.setChildOrderId(childOrderId);
        orderGoods.setChildOrderCode(childOrderCode);
        orderGoods.setGoodsId(product.getGoodsId());
        orderGoods.setGoodsName(service.getServiceName());
//                orderGoods.setGoodsSn();
        orderGoods.setProductId(product.getId());
        orderGoods.setPrice(product.getPrice());
        orderGoods.setNumber(product.getPartsNumber() == 1 ? 1 : selectedSpecInfo.getStock().shortValue());
        orderGoods.setSpecifications(product.getSpecifications());
        orderGoods.setPicUrl(product.getUrl());
//        orderGoods.setGoodsGroupId(cart.getGoodsGroupId());
        orderGoods.setSaleUserId(null == saleUserId ? null : saleUserId + "");
//                orderGoods.setStoreId();
        orderGoods.setOrderGoodsStat(OrderUtil.STATUS_CREATE.intValue());
        orderGoods.setType(OrderGoodsConstant.TYPE_EXTEND);
        orderGoods.setPartentId(parentId);
        orderGoods.setSpecInfoId(null == litemallGoodsSpecification ? null : litemallGoodsSpecification.getParentId());
        orderGoodsService.add(orderGoods);

        return orderGoods;
    }

    private LitemallOrderGoods saveOrderParts(AgedmallStore store, StoreGoodsVo mainGoods, StoreGoodsProductVo product, StoreGoodsVo goods, SelectedSpecInfo selectedSpecInfo, Integer orderId, Integer parentId, Integer saleUserId
            , long childOrderId, String bigOrderCode, String childOrderCode) {
        // 获取指定类型库存
        int stockNum = 0;
        if (InventoryUtil.STOCK_CLOUD.equals(selectedSpecInfo.getStockType())) {
            stockNum = inventoryUtil.get(selectedSpecInfo.getCloudStockId(), InventoryUtil.TYPE_CLOUD, selectedSpecInfo.getStockType(), goods.getId(), product.getId());
        } else {
            stockNum = inventoryUtil.get(goods.getStoreId(), InventoryUtil.TYPE_STORE, selectedSpecInfo.getStockType(), goods.getId(), product.getId());
        }
        int remainNumber = stockNum - selectedSpecInfo.getStock();
        if (remainNumber < 0) {
            throw new BizException("下单的商品货品数量大于库存量");
        }

        LitemallOrderGoods orderGoods = new LitemallOrderGoods();
        orderGoods.setOrderId(orderId);
        orderGoods.setChildOrderId(childOrderId);
        orderGoods.setOrderCode(bigOrderCode);
        orderGoods.setChildOrderCode(childOrderCode);
        orderGoods.setGoodsId(product.getGoodsId());
        orderGoods.setStoreGoodsId(goods.getStoreGoodsId());
        orderGoods.setGoodsName(goods.getName());
        orderGoods.setGoodsSn(goods.getGoodsSn());
        orderGoods.setProductId(product.getId());
        orderGoods.setStoreProductId(product.getStoreProductId());
        orderGoods.setPrice(product.getSaleRetailPrice());
        orderGoods.setNumber(product.getPartsNumber() == 1 ? 1 : selectedSpecInfo.getStock().shortValue());
        orderGoods.setSpecifications(product.getSpecifications());
        orderGoods.setPicUrl(product.getUrl());
//                orderGoods.setGoodsGroupId(cart.getGoodsGroupId());
        orderGoods.setSaleUserId(null == saleUserId ? null : saleUserId + "");
        orderGoods.setStoreId(goods.getStoreId());
        orderGoods.setOrderGoodsStat(OrderUtil.STATUS_CREATE.intValue());
        orderGoods.setType(OrderGoodsConstant.TYPE_CUSTOM);
        orderGoods.setPartentId(parentId);
        Integer specInfoId = litemallGoodsSpecificationService.getSpecInfoIdByGoodsId(mainGoods.getId(), goods.getId());
        orderGoods.setSpecInfoId(specInfoId);
        orderGoods.setStockType(selectedSpecInfo.getStockType());
        orderGoods.setCloudStockId(selectedSpecInfo.getCloudStockId());
        orderGoodsService.add(orderGoods);

        // 减少库存
        inventoryUtil.removeBatch(store.getId().intValue(), selectedSpecInfo.getStockType() == 3 ? 1 : 0, selectedSpecInfo.getStockType(),
                goods.getId(), product.getId(), product.getPartsNumber() == 1 ? 1 : selectedSpecInfo.getStock());

        return orderGoods;
    }

    private LitemallOrderGoods saveOrderGoods(AgedmallStore store, StoreGoodsVo goods, StoreGoodsProductVo product, SelectedSpecInfo selectedGoodsSpec,
                                              Integer bigOrderId, TempSubOrderGoods tempSubOrderGoods, long childOrderId, String bigOrderCode, String childOrderCode,
                                              TempSubOrderParamDelivery delivery) {
        // 获取指定类型库存
        int stockNum = 0;
        //获取软链库存goodsEqu的type  2为医院库存
        int type=0;
//        如果为到院自提
        AgedmallHospitalSendSelfLocation selfLocation = null;
        if(delivery.getHospital()!=null&&delivery.getHospital().getPosId()!=null){
             selfLocation = agedmallHospitalSendSelfLocationMapper.selectByPrimaryKey(delivery.getHospital().getPosId());
        }
        if(ObjectUtil.isNotNull(selfLocation)&&selfLocation.getInventoryFlag()==0){
            List<Long> canUseHospitalEquIdList = appOrderMapper.getCanUseHospitalEquIdList(delivery.getHospital().getPosId());
            stockNum=canUseHospitalEquIdList.size();
            type=2;
            //如果为医院库存  设置为软链锁
            tempSubOrderGoods.setStockType(InventoryUtil.STOCK_SOFTCHAIN);
        }
        else if (InventoryUtil.STOCK_CLOUD.equals(tempSubOrderGoods.getStockType())) {
            stockNum = inventoryUtil.get(tempSubOrderGoods.getCloudStockId(), InventoryUtil.TYPE_CLOUD, tempSubOrderGoods.getStockType(), goods.getId(), product.getId());
        } else {
            stockNum = inventoryUtil.get(goods.getStoreId(), InventoryUtil.TYPE_STORE, tempSubOrderGoods.getStockType(), goods.getId(), product.getId());
        }
        int remainNumber = stockNum - selectedGoodsSpec.getStock();
        if (remainNumber < 0) {
            throw new BizException("下单的商品货品数量大于库存量");
        }

        LitemallOrderGoods orderGoods = new LitemallOrderGoods();
        LitemallOrderItem orderItem = litemallOrderItemMapper.selectByPrimaryKey((int) childOrderId);
        //判断当前是否是软链锁库存  到桩自提必须是软链锁库存，否则返回错误
        if ((isHospitalSelfDelivery(delivery) && !InventoryUtil.STOCK_SOFTCHAIN.equals(tempSubOrderGoods.getStockType()))
                &&type!=2) {
            throw new BizException("当前没有可到桩自提的商品");
        }
        orderGoods.setChildOrderId(childOrderId);
        orderGoods.setChildOrderCode(childOrderCode);
        orderGoods.setOrderCode(bigOrderCode);
        boolean flag = GoodsConstant.GOODS_TYPE_LEASE.equals(goods.getGoodsType());
//        if (flag) {
        // 软链医柜类型查询并锁定rfid
        LockGoodsVo lockGoodsVo = new LockGoodsVo();
        lockGoodsVo.setStoreId(store.getId());
        lockGoodsVo.setGoodsId(goods.getId());
        lockGoodsVo.setSpecId(product.getId());
        lockGoodsVo.setNumber(selectedGoodsSpec.getStock());
        lockGoodsVo.setType(type);
        lockGoodsVo.setHospitalSelfLocationId(type==2?selfLocation:null);
        if (InventoryUtil.STOCK_SOFTCHAIN.equals(tempSubOrderGoods.getStockType())) {
            List<String> rfids = lockRfidUtil.lockGoods(lockGoodsVo);
            if (CollectionUtils.isEmpty(rfids)) {
                throw new BizException("下单的商品货品数量大于库存量");
            }
            orderGoods.setRfid(String.join(",", rfids));
        }
        if (InventoryUtil.STOCK_CABINET.equals(tempSubOrderGoods.getStockType())) {
            List<String> rfids = lockRfidUtil.lockCabinetGoods(lockGoodsVo);
            if (CollectionUtils.isEmpty(rfids)) {
                throw new BizException("下单的商品货品数量大于库存量");
            }
            orderGoods.setRfid(String.join(",", rfids));
        }
//        }

        orderGoods.setOrderId(bigOrderId);
        orderGoods.setGoodsId(goods.getId());
        orderGoods.setStoreGoodsId(goods.getStoreGoodsId());
        orderGoods.setGoodsName(goods.getName());
        orderGoods.setGoodsSn(goods.getGoodsSn());
        orderGoods.setProductId(product.getId());
        orderGoods.setStoreProductId(product.getStoreProductId());
        orderGoods.setPrice(flag ? product.getLeaseDeposit() : product.getSaleRetailPrice());
        orderGoods.setNumber(selectedGoodsSpec.getStock().shortValue());
        orderGoods.setSpecifications(product.getSpecifications());
        orderGoods.setPicUrl(product.getUrl());
//        orderGoods.setGoodsGroupId(goods.getGoodsGroupId());
        orderGoods.setSaleUserId(null == tempSubOrderGoods.getSaleUserId() ? null : tempSubOrderGoods.getSaleUserId() + "");
        orderGoods.setStoreId(goods.getStoreId());
        orderGoods.setOrderGoodsStat(OrderUtil.STATUS_CREATE.intValue());
        orderGoods.setType(OrderGoodsConstant.TYPE_GOODS);
//        orderGoods.setGoodsType(cart.getGoodsType());
        orderGoods.setStockType(tempSubOrderGoods.getStockType());
        orderGoods.setCloudStockId(tempSubOrderGoods.getCloudStockId());
        orderGoods.setPayStyle(goods.getPayOrder());
        orderGoods.setHospitalSelfLocationId(delivery.getHospital()!=null?delivery.getHospital().getPosId():null);
        orderGoods.setLocationType(selfLocation==null?null:selfLocation.getInventoryFlag());
        orderGoods.setLocationHpType(selfLocation==null?null:selfLocation.getHpFlag());
        orderGoods.setRuleId(tempSubOrderGoods.getRuleId());
        orderGoodsService.add(orderGoods);

        // 减少库存
        inventoryUtil.removeBatch(store.getId().intValue(), tempSubOrderGoods.getStockType() == 3 ? 1 : 0, tempSubOrderGoods.getStockType(),
                goods.getId(), product.getId(), selectedGoodsSpec.getStock());

        return orderGoods;
    }

    private boolean isHospitalSelf(LitemallOrderItem orderItem,LitemallOrderGoods orderGoods) {
        if (orderItem.getDeliverySn() != null && orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
            JSONObject jsonObject = JSON.parseObject(orderItem.getDeliveryChoose());
            String type = (String) jsonObject.get("type");
            if (type.equals("subHospitalSelf")) {
                return true;
            }
        }
        return false;
    }

    private boolean isHospitalSelfDelivery(TempSubOrderParamDelivery delivery) {
        if (delivery.getType().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
            if (delivery.getHospital().getType().equals("subHospitalSelf")) {
                return true;
            }
        }
        return false;
    }


    private String getOrderSn() {
        // 时间戳加自增数据库6位id
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        int number = agedmallOrderSerialService.add();
        return time + StringUtils.leftPad(number + "", 6, "0");
    }

    /**
     * 创建微信支付订单
     *
     * @param userId
     * @param bigOrderId
     * @param code
     * @param isCredit
     * @param spbillCreateIp
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public BaseResult createWxPayOrder(Integer userId, String bigOrderId, String code, Integer isCredit, String spbillCreateIp) throws CheckException {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder order = litemallOrderService.findBySn(userId, bigOrderId);
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isPay()) {
            throw new BizException("订单不能支付");
        }

        String openId = null;
        try {
            WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
            openId = result.getOpenid();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null == openId) {
            return RespUtil.badArgumentValue();
        }
        // 元转成分
        int fee = 0;
        BigDecimal actualPrice = order.getActualPrice();
        fee = actualPrice.multiply(new BigDecimal(100)).intValue();
        // 开发测试
//        fee = 1;

        JSONObject object = new JSONObject();
        object.put("bigOrderId", order.getOrderSn());


        if (isCredit == 0) {
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setOutTradeNo(order.getOrderSn());
            orderRequest.setOpenid(openId);
            orderRequest.setBody("订单：" + order.getOrderSn());
            orderRequest.setTotalFee(fee);
            orderRequest.setSpbillCreateIp(spbillCreateIp);
            orderRequest.setNotifyUrl(wxPayConfig.getNotifyUrl());

            WxPayMpOrderResult wxPayMpOrderResult = null;
            try {
                wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
            } catch (WxPayException e) {
                e.printStackTrace();
                return RespUtil.fail();
            }
            object.put("weixinPayment", wxPayMpOrderResult);
        } else {

            BaseResult result = wxPayScoreTool.createPayScoreOrder(openId, order.getOrderSn(), fee);
            Object wxPayScoreResultObj = result.getData();
            if (wxPayScoreResultObj == null) {
                return RespUtil.fail(ResultCode.WX_NODEPOSIT_ERR_CREATE_FAIL);
            }
            WxPayScoreResult wxPayScoreResult = (WxPayScoreResult) wxPayScoreResultObj;

            //记录商户订单与服务订单关系信息
            List<LitemallOrderItem> childOrderCodeList = litemallOrderService.queryOrderItemListByBigOrderCode(bigOrderId);
            for (LitemallOrderItem item : childOrderCodeList) {
                String childOrderCode = item.getChildOrderCode();
                AgedmallWxNodepositRecord nodepositRecord = new AgedmallWxNodepositRecord();
                nodepositRecord.setCreated(LocalDateTime.now());
                nodepositRecord.setLeaseOrderCode(bigOrderId);
                nodepositRecord.setLeaseWxOrderId(wxPayScoreResult.getOrderId());
                nodepositRecord.setLeaseWxServiceId(wxPayScoreResult.getServiceId());
                nodepositRecord.setWxStat(wxPayScoreResult.getState());
                nodepositRecord.setChildOrderCode(childOrderCode);
                agedmallWxNoDepositService.recordCreateNoDepositInfo(nodepositRecord);
            }

            Map<String, String> signMap = wxPayScoreResult.getPayScoreSignInfo();
            Map<String, String> resultMap = new HashMap();
            resultMap.put("mchId", signMap.get("mch_id"));
            resultMap.put("packageValue", signMap.get("package"));
            resultMap.put("timestamp", signMap.get("timestamp"));
            resultMap.put("nonceStr", signMap.get("nonce_str"));
            resultMap.put("signType", signMap.get("sign_type"));
            resultMap.put("sign", signMap.get("sign"));
            object.put("weixinCreditLease", resultMap);
        }

        return RespUtil.success(object);
    }

    public BaseResult wxQueryOrder(Integer userId, String bigOrderId) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder order = litemallOrderService.findBySn(userId, bigOrderId);
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        return RespUtil.success(wxQueryOrder(order));
    }

    public BaseResult wxQueryPayScoreOrder(Integer userId, String bigOrderId) {
        if (userId == null) {
            return RespUtil.unlogin();
        }
        LitemallOrder order = litemallOrderService.findBySn(userId, bigOrderId);
        if (null == order) {
            return RespUtil.badArgumentValue();
        }
        return RespUtil.success(wxQueryPayScoreOrder(order));
    }

    private short wxQueryOrder(LitemallOrder order) {
        WxPayOrderQueryResult result = null;
        try {
            result = wxPayService.queryOrder(null, order.getOrderSn());
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        if (null != result && WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode()) && WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
            String payId = result.getTransactionId();
            String payOpenId = result.getOpenid();

            if ("SUCCESS".equals(result.getTradeState())) {
                ThreadPoolPaySuccess.PAY_SUCCESS_THREAD_POOL.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            paySuccess(order, payId, payOpenId, AgedmallCashoutConstant.CHANNEL_WEIXIN);
                        } catch (Exception ex) {
                            logger.error("支付成功订单更新失败{},{}", order.getOrderSn(), ex);
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                            }
                            paySuccess(order, payId, payOpenId, AgedmallCashoutConstant.CHANNEL_WEIXIN);
                        }
                    }
                });
                return OrderUtil.STATUS_PAY;
            } else {
                return OrderUtil.STATUS_CREATE;
            }
        } else {
            return OrderUtil.STATUS_CREATE;
        }
    }

    private short wxQueryPayScoreOrder(LitemallOrder order) {
        WxPayScoreResult result = wxPayScoreTool.payScoreQuery(order.getOrderSn());
        if (null != result && !"CREATED".equals(result.getState())) {
            String payId = result.getOrderId();
            ThreadPoolPaySuccess.PAY_SUCCESS_THREAD_POOL.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        paySuccess(order, payId, null, AgedmallCashoutConstant.CHANNEL_WEIXINPAYSCORE);
                    } catch (Exception ex) {
                        logger.error("支付成功订单更新失败{},{}", order.getOrderSn(), ex);
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                        }
                        paySuccess(order, payId, null, AgedmallCashoutConstant.CHANNEL_WEIXINPAYSCORE);
                    }
                }
            });
            return OrderUtil.STATUS_PAY;
        } else {
            return OrderUtil.STATUS_CREATE;
        }
    }

    @Transactional
    public Object payNotify(HttpServletRequest request, HttpServletResponse response) {
        logger.info("----------------------------收到回调----------------------------------");
        String xmlResult = null;
        try {
            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
        } catch (IOException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        WxPayOrderNotifyResult result = null;
        try {
            result = wxPayService.parseOrderNotifyResult(xmlResult);

            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getResultCode())) {
                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败！");
            }
            if (!WxPayConstants.ResultCode.SUCCESS.equals(result.getReturnCode())) {
                logger.error(xmlResult);
                throw new WxPayException("微信通知支付失败！");
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        String orderSn = result.getOutTradeNo();
        String payId = result.getTransactionId();
        String payOpenId = result.getOpenid();

        LitemallOrder order = litemallOrderService.findBySn(orderSn);
        if (order == null) {
            return WxPayNotifyResponse.fail("订单不存在 sn=" + orderSn);
        }
        ThreadPoolPaySuccess.PAY_SUCCESS_THREAD_POOL.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    paySuccess(order, payId, payOpenId, AgedmallCashoutConstant.CHANNEL_WEIXIN);
                } catch (Exception ex) {
                    logger.error("支付成功订单更新失败{},{}", order.getOrderSn(), ex);
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                    }
                }
            }
        });

        return WxPayNotifyResponse.success("处理成功!");
    }

    @Transactional
    public Object payScoreNotify(HttpServletRequest request) {
        JSONObject result = new JSONObject();
        WxPayScoreResult payScoreResult = null;
        try {
            payScoreResult = wxPayScoreTool.payScoreNotifyRst(request);
        } catch (WxPayException | IOException e) {
            e.printStackTrace();
            result.put("code", "FAIL");
            result.put("message", e.getMessage());
            return result;
        }

        String state = payScoreResult.getState();
        String outOrderCode = payScoreResult.getOutOrderNo();
        agedmallWxNoDepositService.updateNoDepositStat(outOrderCode, state);
        if (WX_PAY_SCORE_STATE_DONE.equals(state)) {
            String orderSn = payScoreResult.getOutOrderNo();
            LitemallOrder order = litemallOrderService.findBySn(orderSn);
            if (order == null) {
                logger.error("免押订单不存在{}", orderSn);
                result.put("code", "FAIL");
                result.put("message", "订单不存在 sn=" + orderSn);
                return result;
            }
            payScoreDoneSuc(orderSn, order.getUserId().intValue());
        }

        result.put("code", "SUCCESS");
        return result;
    }

    /**
     * 支付分订单完结
     */
    private void payScoreDoneSuc(String outOrderCode, int uid) {
        agedmallWxNoDepositService.updateNoDepositDoneSuc(outOrderCode);
        litemallOrderService.updateNoDepositOrderStatus(outOrderCode, OrderUtil.STATUS_PAY);
    }

    private void paySuccess(LitemallOrder order, String payId, String payOpenId, String payType) {
        // 检查这个订单是否已经处理过
        order = litemallOrderService.findOrderByOrderCode(order.getOrderSn());
        if (!OrderUtil.hasPayed(order)) {
            order.setPayType(payType);
            order.setPayId(payId);
            order.setPayTime(LocalDateTime.now());
            order.setPayOpenId(payOpenId);
            order.setOrderStatus(OrderUtil.STATUS_PAY);
            litemallOrderService.update(order);

            List<LitemallOrderItem> subOrder = litemallOrderService.getOrderItemListByBigOrderCode(order.getUserId(), order.getOrderSn());
            for (LitemallOrderItem orderItem : subOrder) {
                litemallOrderService.updateChildOrderStatus(orderItem.getChildOrderCode(), OrderUtil.STATUS_PAY);
                //修改分成表支付状态
                AgedmallPromoteSettlementExample promoteSettlementExample = new AgedmallPromoteSettlementExample();
                promoteSettlementExample.createCriteria().andItemsIdEqualTo(orderItem.getId());
                AgedmallPromoteSettlement promoteSettlement = new AgedmallPromoteSettlement();
                promoteSettlement.setPayAmount(orderItem.getActualPrice());
                promoteSettlement.setSettlementType(1L);//表示已支付
                agedmallPromoteSettlementMapper.updateByExampleSelective(promoteSettlement, promoteSettlementExample);

                // 订单商品 售卖数量加1
                List<LitemallOrderGoods> orderGoodsList = orderGoodsService.getOrderGoodsListByChildOrderCode(orderItem.getChildOrderCode());
                for (LitemallOrderGoods orderGoods : orderGoodsList) {
                    if (!OrderGoodsConstant.TYPE_EXTEND.equals(orderGoods.getType())) {
                        agedmallGoodsSaleInfoService.addSaleCountByGoodsId(orderGoods.getGoodsId());
                    }
//                    if (StringUtils.isNotEmpty(orderGoods.getRfid())) {
//                        // rfid待发货通知
//                        softChainLockManager.updateRfidStatus(orderGoods.getRfid());
//                    }
                }
//                // 加入通知,待发送
//                AgedmallOrderMsg agedmallOrderMsg = orderService.getOrderMsgInfo(litemallOrder.getId());
//                agedmallOrderMsg.setType(AgedmallOrderMsgConstant.TYPE_ORDER);
//                agedmallOrderMsg.setStatus(AgedmallOrderMsgConstant.STATUS_ADD);
//                agedmallOrderMsgService.add(agedmallOrderMsg);
//                // 提醒播报打印机 可刷卡打印
//                announcerManager.orderNotice(agedmallOrderMsg.getDeviceId());
//                // 怕提醒遗漏 发短信给商家和门店配送员
//                AgedmallStore agedmallStore = agedmallStoreService.getAgedmallBusiAdminByStoreId(agedmallOrderMsg.getStoreId());
//                if (null != agedmallStore) {
//                    notifyService.notifySmsTemplate(agedmallStore.getPhone(), NotifyType.ANNOUNCER, new String[]{litemallOrder.getOrderSn() + ""});
//                }
//                AgedmallDeliveryManInfo agedmallDeliveryManInfo = agedmallStoreService.getAgedmallDeliveryManInfoByStoreId(agedmallOrderMsg.getStoreId());
//                if (null != agedmallDeliveryManInfo) {
//                    notifyService.notifySmsTemplate(agedmallDeliveryManInfo.getPhone(), NotifyType.ANNOUNCER, new String[]{litemallOrder.getOrderSn() + ""});
//                }
            }
            // 更新服务订单状态
            AgedmallServiceOrderExample serviceOrderExample = new AgedmallServiceOrderExample();
            serviceOrderExample.createCriteria().andDeletedEqualTo(false)
                    .andOrderIdEqualTo(order.getId().longValue());
            List<AgedmallServiceOrder> serviceOrderList = agedmallServiceOrderMapper.selectByExample(serviceOrderExample);
            for (AgedmallServiceOrder serviceOrder : serviceOrderList) {
                if (null == serviceOrder.getFullAppointTime()) {
                    serviceOrder.setStat(ServiceOrderConstant.STATUS_WAIT_APPOINTMENT);
                } else {
                    serviceOrder.setStat(ServiceOrderConstant.STATUS_WAIT_ORDER);
                }
                agedmallServiceOrderMapper.updateByPrimaryKey(serviceOrder);
            }

            // 取消订单超时未支付任务
            taskService.removeTask(new OrderUnpaidTask(order.getId()));

            // 分包
            //发送订单通知
            if(environmentConstant.getEnv().equals("online")){
                ReceivedBean receivedBean = new ReceivedBean();
                receivedBean.setType(3);
                GetTextContent textContent=new GetTextContent();
                textContent.setContent("来了一个新订单:"+ DateUtil.now());
                textContent.setChatId("wlOnlineOrderNotice");
                receivedBean.setGetTextContent(textContent);
                directExchangeProducer.send(JSONUtil.toJsonStr(receivedBean), DirectExchangeRabbitMQConfig.TO_WECHAT_NOTICE);
            }
            packageService.subpackage(order.getId());
        }
    }

    public BaseResult wxRefund(String orderId) {
        LitemallOrder order = litemallOrderService.findById(Integer.parseInt(orderId));
        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer totalFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(totalFee);

        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            logger.error(e.getMessage(), e);
            throw new BizException("订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new BizException("订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new BizException("订单退款失败");
        }
        return RespUtil.success();
    }

    public BaseResult wxRefund(String orderId, BigDecimal amount) {
        LitemallOrder order = litemallOrderService.findById(Integer.parseInt(orderId));
        if (amount.compareTo(order.getActualPrice()) > 0) {
            throw new BizException("退款金额大于总额");
        }
        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer totalFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        Integer refundFee = amount.multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(refundFee);

        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            logger.error(e.getMessage(), e);
            throw new BizException("订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new BizException("订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new BizException("订单退款失败");
        }
        return RespUtil.success();
    }


    public BaseResult autoConfirm(String orderId) {
        // 添加自动确认订单任务
        taskService.addTask(new OrderUnconfirmTask(Integer.parseInt(orderId)));
        return RespUtil.success();
    }

    /**
     * 获取门店商品库存
     *
     * @param storeGoodsVo
     * @param specId
     * @return
     */
    public Integer getByStoreGoods(StoreGoodsVo storeGoodsVo, Integer specId) {
        int total = 0;
        // 门店库存不使用会传-1，使用传数量。其他库存使用1，不使用0
        if (null != storeGoodsVo.getGoodsStock() && storeGoodsVo.getGoodsStock() >= 0) {
            // 1 门店
            int num1 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_STORE, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，门店：{}", storeGoodsVo.getStoreGoodsId(), num1);
            total += num1;
        }
        if (null != storeGoodsVo.getChainLock() && storeGoodsVo.getChainLock() > 0) {
            // 2 链条
            int num2 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_SOFTCHAIN, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，软链：{}", storeGoodsVo.getStoreGoodsId(), num2);
            total += num2;
        }
        if (null != storeGoodsVo.getCabinetLock() && storeGoodsVo.getCabinetLock() > 0) {
            // 3 医柜
            int num3 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_CABINET, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，医柜：{}，", storeGoodsVo.getStoreGoodsId(), num3);
            total += num3;
        }
        if (null != storeGoodsVo.getCloudLock() && storeGoodsVo.getCloudLock() > 0) {
            // 4 云仓
            int num4 = 0;
            List<Integer> cloudIds = agedmallCloudHouseService.getIdsByGoodsProduct(storeGoodsVo.getId(), specId);
            for (Integer cloudId : cloudIds) {
                int num = inventoryUtil.get(cloudId, InventoryUtil.TYPE_CLOUD, InventoryUtil.STOCK_CLOUD, storeGoodsVo.getId(), specId);
                num4 += num;
            }
            logger.debug("门店商品id：{}库存信息，云仓：{}", storeGoodsVo.getStoreGoodsId(), num4);
            total += num4;
        }
        return total;
    }

    /**
     * 获取门店商品库存
     *
     * @param storeGoodsVo
     * @param specId
     * @return
     */
    public Integer getByStoreGoods(StoreGoodsVo storeGoodsVo, Integer specId, Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsProductMap) {
        int total = 0;
        // 门店库存不使用会传-1，使用传数量。其他库存使用1，不使用0
        if (null != storeGoodsVo.getGoodsStock() && storeGoodsVo.getGoodsStock() >= 0) {
            // 1 门店
            int num1 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_STORE, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，门店：{}", storeGoodsVo.getStoreGoodsId(), num1);
            total += num1;
        }
        if (null != storeGoodsVo.getChainLock() && storeGoodsVo.getChainLock() > 0) {
            // 2 链条
            int num2 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_SOFTCHAIN, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，软链：{}", storeGoodsVo.getStoreGoodsId(), num2);
            total += num2;
        }
        if (null != storeGoodsVo.getCabinetLock() && storeGoodsVo.getCabinetLock() > 0) {
            // 3 医柜
            int num3 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_CABINET, storeGoodsVo.getId(), specId);
            logger.debug("门店商品id：{}库存信息，医柜：{}，", storeGoodsVo.getStoreGoodsId(), num3);
            total += num3;
        }
        if (null != storeGoodsVo.getCloudLock() && storeGoodsVo.getCloudLock() > 0) {
            // 4 云仓
            int num4 = 0;


            List<Long> cList = null;
            List<AgedmallCloudGoodsProduct> pList = cloudGoodsProductMap.get(storeGoodsVo.getId());
            if (pList == null) {
                cList = new ArrayList<>();
            } else {
                if (specId == null) {
                    cList = pList.parallelStream().map(AgedmallCloudGoodsProduct::getCloudId).collect(Collectors.toList());
                } else {
                    pList = pList.stream().filter(cp -> cp.getGoodsProductId().equals(Long.parseLong(specId.toString()))).collect(Collectors.toList());
                    cList = pList.parallelStream().map(AgedmallCloudGoodsProduct::getCloudId).collect(Collectors.toList());
                }
            }
            List<Integer> cloudIds = new ArrayList<>();
            cList.stream().forEach(c -> {
                cloudIds.add(c.intValue());
            });

            for (Integer cloudId : cloudIds) {
                int num = inventoryUtil.get(cloudId, InventoryUtil.TYPE_CLOUD, InventoryUtil.STOCK_CLOUD, storeGoodsVo.getId(), specId);
                num4 += num;
            }
            logger.debug("门店商品id：{}库存信息，云仓：{}", storeGoodsVo.getStoreGoodsId(), num4);
            total += num4;
        }
        return total;
    }


    /**
     * 获取商品库存类型,若为云仓，一并返回云仓id
     *
     * @param storeGoodsVo
     * @param specId
     * @return
     */
    public StockTypeDto getStockTypeByStoreGoods(StoreGoodsVo storeGoodsVo, Integer specId, BigDecimal lng, BigDecimal lat) {
        // 门店库存不使用会传-1，使用传数量。其他库存使用1，不使用0
        if (null != storeGoodsVo.getChainLock() && storeGoodsVo.getChainLock() > 0) {
            // 链条
            int num1 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_SOFTCHAIN, storeGoodsVo.getId(), specId);
            if (num1 > 0) {
                return new StockTypeDto(InventoryUtil.STOCK_SOFTCHAIN);
            }
        }
        if (null != storeGoodsVo.getCabinetLock() && storeGoodsVo.getCabinetLock() > 0) {
            // 医柜
            int num2 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_CABINET, storeGoodsVo.getId(), specId);
            if (num2 > 0) {
                return new StockTypeDto(InventoryUtil.STOCK_CABINET);
            }
        }
        if (null != storeGoodsVo.getGoodsStock() && storeGoodsVo.getGoodsStock() >= 0) {
            // 门店
            int num3 = inventoryUtil.get(storeGoodsVo.getStoreId(), InventoryUtil.TYPE_STORE, InventoryUtil.STOCK_STORE, storeGoodsVo.getId(), specId);
            if (num3 > 0) {
                return new StockTypeDto(InventoryUtil.STOCK_STORE);
            }
        }
        if (null != storeGoodsVo.getCloudLock() && storeGoodsVo.getCloudLock() > 0) {
            List<Integer> cloudIds;
            // 云仓 获取最近且有库存的云仓库存
            if (StringUtils.isNotBlank(storeGoodsVo.getCloudId())) {
                cloudIds = new ArrayList<>();
                String[] splitCloudIds = storeGoodsVo.getCloudId().split(",");
                for (int i = 0; i < splitCloudIds.length; i++) {
                    cloudIds.add(Integer.parseInt(splitCloudIds[i]));
                }
            } else {
                cloudIds = agedmallCloudHouseService.getIdsByGoodsProductAndLngLat(storeGoodsVo.getId(), specId, lng, lat);
            }
            for (Integer cloudId : cloudIds) {
                int num = inventoryUtil.get(cloudId, InventoryUtil.TYPE_CLOUD, InventoryUtil.STOCK_CLOUD, storeGoodsVo.getId(), specId);
                if (num > 0) {
                    return new StockTypeDto(InventoryUtil.STOCK_CLOUD, cloudId);
                }
            }
        }
        return null;
    }

    /**
     * 前端 ——》 数据库状态
     *
     * @param status
     * @param type 0-配货  1-送货  2-取回 3-维护
     * @return
     */
    public Integer webToDbOrderListStat(Integer status, Integer type) {
        switch (type) {
            case 0:
                switch (status) {
                    case 0:
                        return 100;
                    case 1:
                        return 1;
                    case 2:
                        return 2;
                    case 3:
                        return 3;
                    default:
                        return null;
                }
            case 1:
            case 2:
            case 3:
                switch (status) {
                    case 0:
                        return 100;
                    case 1:
                        return 0;
                    case 2:
                        return 1;
                    case 3:
                        return 2;
                    case 4:
                        return 3;
                    case 5:
                        return 5;
                    default:
                        return null;
                }
            default:
                return null;
        }

    }


    /**
     * 数据库状态 ——》前端状态
     *
     * @param status
     * @param type
     * @return
     */
    public Integer dbToWebOrderListStat(Integer status, Integer type) {
        switch (type) {
            case 0:
                switch (status) {
                    case 0:
                        return 100;
                    case 1:
                        return 1;
                    case 2:
                        return 2;
                    case 3:
                        return 3;
                    case 5:
                        return 5;
                    default:
                        return null;
                }
            case 1:
            case 2:
            case 3:
                switch (status) {
                    case 0:
                        return 1;
                    case 1:
                        return 2;
                    case 2:
                        return 3;
                    case 3:
                        return 4;
                    case 5:
                        return 5;
                    default:
                        return null;
                }
            default:
                return null;
        }

    }

    public String concatTimeString(String deliverySn, String deliveryChoose, LocalDateTime time, boolean isExpress) {
        String backTime = null;
        if (isExpress) {
            backTime = "快递物流";
            return backTime;
        }
        //自提
        else if(deliverySn.equals(AgedmallShipDictConstant.SHIP_SN_SELF)){
            backTime="门店自提";
            return backTime;
        }
        //加急
        else if (deliverySn.equals(AgedmallShipDictConstant.SHIP_SN_URGENT)) {
            JSONObject jsonObject = JSON.parseObject(deliveryChoose);
            Integer earlyHour = (Integer) jsonObject.get("earlyUrgentPay");
            Integer laterHour = (Integer) jsonObject.get("lastUrgentPay");
            Integer lastHour = laterHour + earlyHour;
            Date addTime = Date.from(time.
                    atZone(ZoneId.systemDefault()).toInstant());
            DateTime earlyDay = cn.hutool.core.date.DateUtil.offsetHour(addTime, earlyHour);
            DateTime lastDay = cn.hutool.core.date.DateUtil.offsetHour(addTime, lastHour);
            String earlyFormat = cn.hutool.core.date.DateUtil.format(earlyDay, "yyyy-MM-dd HH:mm");
            String lastFormat = cn.hutool.core.date.DateUtil.format(lastDay, "HH:mm");
            backTime = "加急配送 (" + earlyFormat + "-" + lastFormat + ")";
            return backTime;
        }
        //预约
        else if (deliverySn.equals(AgedmallShipDictConstant.SHIP_SN_SUBSCRIBE)) {
            JSONObject jsonObject = JSON.parseObject(deliveryChoose);
            String date = (String) jsonObject.get("date");
            String startTime = (String) jsonObject.get("startTime");
            String endTime = (String) jsonObject.get("entTime");
            backTime = "预约配送 (" + date + " " + startTime + "-" + endTime + ")";
            return backTime;
        } else if (deliverySn.equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {

            JSONObject jsonObject = JSON.parseObject(deliveryChoose);
            String date = (String) jsonObject.get("date");
            String startTime = (String) jsonObject.get("startTime");
            String endTime = (String) jsonObject.get("endTime");
            String type = (String) jsonObject.get("type");
//            if (type.equals("subscribe")) {
//                backTime = "医院预约 (" + date + " " + startTime + "-" + endTime + ")";
//            } else {
//                backTime = "医院加急 (" + date + " " + startTime + "-" + endTime + ")";
//            }
            //预约小时达
            if (type.equals("subHourReach")) {
                backTime = "预约小时达 (" + date + " " + startTime + "-" + endTime + ")";
            }
            //预约门店自提
            else if (type.equals("subStoreSelf")) {
                backTime = "预约门店自提 (" + date + " " + startTime + "-" + endTime + ")";
            }
            //到桩自提
            else if (type.equals("subHospitalSelf")) {
                backTime = "到桩自提 (" + date + " " + startTime + "-" + endTime + ")";
            }
            //今日小时达
            else if (type.equals("dayHourReach")) {
                backTime = "小时达 (" + date + " " + startTime + "-" + endTime + ")";
            }
            //今日门店自提
            else if (type.equals("dayStoreSelf")) {
                backTime = "门店自提";
            }
            return backTime;
        } else {
            backTime = "普通配送";
            return backTime;
        }
    }


    /**
     * @param type 0-配货  1-送货  2-取回 3-维护
     * @return
     */
    public Object packerOrderList(PackerOrderListVo packerOrderListVo, Integer userId, Integer type) {
        List<PackageOrderListForm> rows = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        PackageOrderListBackDto printCodeBean = null;

        AgedmallDeliveryManInfoExample manInfoExample = new AgedmallDeliveryManInfoExample();
        manInfoExample.or().andUserIdEqualTo(userId.longValue()).andDeletedEqualTo(false);
        AgedmallDeliveryManInfo manInfo = agedmallDeliveryManInfoMapper.selectOneByExample(manInfoExample);
        if(manInfo == null) {
            logger.error("用户没有查看物流订单权限{}", userId);
            return RespUtil.fail(ORDER_PACKAGE_NO_AUTH.code(), ORDER_PACKAGE_NO_AUTH.msg());
        }
        List<Integer> missionId = new ArrayList<>();
        if (packerOrderListVo.getStatus() != null && webToDbOrderListStat(packerOrderListVo.getStatus(), type) == 100) {
            missionId = appOrderMapper.getUnOrderMissionIdList(manInfo.getPhone());
            if (missionId == null || missionId.size() == 0) {
                map.put("nowPage", packerOrderListVo.getPage());
                map.put("totalPage", 0);
                map.put("totalRows", 0);
                map.put("rows", null);
                return RespUtil.success(map);
            }
        }
        if (StringUtils.isNotBlank(packerOrderListVo.getPrinterCode())) {
            String[] split = packerOrderListVo.getPrinterCode().split("-");
            if (split.length < 2) {
                return RespUtil.fail(1011, "打印包裹码格式错误");
            }
            Integer missionCode = Integer.parseInt(split[1]);
            List<PackageOrderListBackDto> packageOrderList = appOrderMapper.getPackageOrderList(manInfo.getPhone(),
                    packerOrderListVo.getStatus() == null ? null : webToDbOrderListStat(packerOrderListVo.getStatus(), type), missionCode, type, missionId.size() > 0 ? missionId : null);
            if (ObjectUtil.isNotNull(packageOrderList) && packageOrderList.size() > 0) {
                printCodeBean = packageOrderList.get(0);
            }

        }


        Page page = PageHelper.startPage(packerOrderListVo.getPage(), packerOrderListVo.getPageSize());
        List<PackageOrderListBackDto> packageOrderList = appOrderMapper.getPackageOrderList(manInfo.getPhone(),
                packerOrderListVo.getStatus() == null ? null : webToDbOrderListStat(packerOrderListVo.getStatus(), type), null, type, missionId.size() > 0 ? missionId : null);

        //如果有printCode，置顶
        if (ObjectUtil.isNotNull(printCodeBean) && packageOrderList.size() > 0) {
            boolean isInList = false;
            for (int i = 0; i < packageOrderList.size(); i++) {
                if (packageOrderList.get(i).getId().equals(printCodeBean.getId())) {
                    isInList = true;
                    packageOrderList.remove(i);
                    packageOrderList.add(0, printCodeBean);
                }
            }
            if (!isInList) {
                packageOrderList.remove(packageOrderList.size() - 1);
                packageOrderList.add(0, printCodeBean);
            }
        }
        for (int i = 0; i < packageOrderList.size(); i++) {
            PackageOrderListForm packageOrderListForm = new PackageOrderListForm();
            PackageOrderListBackDto packageOrderListBackDto = packageOrderList.get(i);
            List<Integer> integers = logisticBusiBaseServiceImpl.getorderGoodsIds(packageOrderListBackDto.getLgContent());
            LitemallOrderGoodsExample orderGoodsExample = new LitemallOrderGoodsExample();
            orderGoodsExample.or().andIdIn(integers);
            List<LitemallOrderGoods> orderGoodsList = litemallOrderGoodsMapper.selectByExample(orderGoodsExample);
            List<SubOrderGoodsVo> goodsList = getGoodsList(orderGoodsList);
            //商品信息
            packageOrderListForm.setGoodsList(goodsList);
            //门店信息  配货信息
            StoreInfoDto storeInfoDto = null;
            PackageAddressDto packageAddressDto = null;
            if (packageOrderListBackDto.getWarehouseType() == 0) {
                AgedmallStore store = agedmallStoreMapper.selectByPrimaryKey(packageOrderListBackDto.getStoreId().longValue());
                storeInfoDto = new StoreInfoDto(store);
                packageAddressDto = new PackageAddressDto(store);
                if (store.getDeliveryMode() == 3) {
                    packageOrderListForm.setIsExpress(1);
                    packageOrderListForm.setAutoExpress(1);
                    ExpressInfo expressInfo = new ExpressInfo();
                    expressInfo.setName(store.getThirdLogisticsName());
                    expressInfo.setPhone(store.getThirdLogisticsPhone());
                    packageOrderListForm.setExpressInfo(expressInfo);
                } else {
                    packageOrderListForm.setIsExpress(0);
                }
            } else {
                AgedmallCloudHouse agedmallCloudHouse = agedmallCloudHouseMapper.selectByPrimaryKey(packageOrderListBackDto.getStoreId());
                storeInfoDto = new StoreInfoDto(agedmallCloudHouse);
                packageAddressDto = new PackageAddressDto(agedmallCloudHouse);
                packageOrderListForm.setIsExpress(1);
                ExpressInfo expressInfo = new ExpressInfo();
                //TODO 云仓未配置物流信息，暂时写死
                expressInfo.setName("顺丰");
                expressInfo.setPhone("95338");
                packageOrderListForm.setExpressInfo(expressInfo);
            }
            packageOrderListForm.setStoreInfo(storeInfoDto);
            if (type == 2) {
                packageOrderListForm.setBackAddress(packageAddressDto);
            } else if (type == 3) {
                packageOrderListForm.setRepairAddress(packageAddressDto);
            } else {
                packageOrderListForm.setPackAddress(packageAddressDto);
            }

            //获取用户地址
            LitemallOrderItem subOrder = litemallOrderService.findItemById(orderGoodsList.get(0).getChildOrderId().intValue());
            UserAddressDto userAddressDto;
            if (type == 2) {
                AgedmallLgBaseInfo baseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(packageOrderListBackDto.getId().longValue());
                LogisticsCommonData commonData = LogisticsGoodsUtil.parseObject(baseInfo.getLgContent());
                if (commonData.getBackUserAddress() != null) {
                    userAddressDto = new UserAddressDto(commonData.getBackUserAddress());
                } else {
                    userAddressDto = new UserAddressDto();
                }
            } else {
                LitemallOrder bigOrder = litemallOrderService.findOrderByOrderCode(orderGoodsList.get(0).getOrderCode());
                userAddressDto = new UserAddressDto(bigOrder);
            }
            LitemallUser litemallUser = litemallUserMapper.selectByPrimaryKey(subOrder.getUserId());
            userAddressDto.setGender(litemallUser.getGender().intValue());
            packageOrderListForm.setUserAddress(userAddressDto);
            //包裹其他参数
            AgedmallLgBusiRecordExample busiRecordExample = new AgedmallLgBusiRecordExample();
            busiRecordExample.or().andMissionIdEqualTo(packageOrderListBackDto.getMissionId().longValue());
            List<AgedmallLgBusiRecord> agedmallLgBusiRecords = agedmallLgBusiRecordMapper.selectByExample(busiRecordExample);
            if (packerOrderListVo.getStatus() != null && webToDbOrderListStat(packerOrderListVo.getStatus(), type) == 100
                    && !packageOrderListBackDto.getMissionIsOver().equals(LgMissionIsOverEum.CANCEL.getCode())
                    && !packageOrderListBackDto.getMissionIsOver().equals(LgMissionIsOverEum.EXCEPTION.getCode())) {
                packageOrderListForm.setStatus(0);
            } else {
                packageOrderListForm.setStatus(dbToWebOrderListStat(packageOrderListBackDto.getMissionIsOver(), type));
            }
            packageOrderListForm.setIsHospital(subOrder.getIsHospital());
            agedmallLgBusiRecords.forEach(busiRecord -> {
                if (busiRecord.getBusiStat() == 1) {
                    packageOrderListForm.setStartTime(cn.hutool.core.date.DateUtil.formatLocalDateTime(busiRecord.getCreatedTime()));
                } else if (busiRecord.getBusiStat() == 2) {
                    packageOrderListForm.setEndTime(cn.hutool.core.date.DateUtil.formatLocalDateTime(busiRecord.getCreatedTime()));
                    //url地址
                    AgedmallLgBusiImgExample busiImgExample = new AgedmallLgBusiImgExample();
                    busiImgExample.or().andLgBusiIdEqualTo(busiRecord.getId());
                    AgedmallLgBusiImg agedmallLgBusiImg = agedmallLgBusiImgMapper.selectOneByExample(busiImgExample);
                    String[] split = agedmallLgBusiImg != null ? agedmallLgBusiImg.getUrl().split(",") : new String[0];
                    packageOrderListForm.setUploadImages(Arrays.asList(split));
                }
            });
            String goodsDeliveryTime = concatTimeString(subOrder.getDeliverySn(), subOrder.getDeliveryChoose(), subOrder.getAddTime(),
                    packageOrderListForm.getIsExpress() == 1);
            packageOrderListForm.setDeliveryInfo(goodsDeliveryTime);
            packageOrderListForm.setPrinterCode("LBB-" + packageOrderListBackDto.getMissionId());
            packageOrderListForm.setExtractQrCode("LBB-"+packageOrderListBackDto.getMissionId());
            packageOrderListForm.setSubOrderId(subOrder.getChildOrderCode());

            Integer isSubHospital = 0;
            if (type == 0) {
                //是否有硬件设备
                List<LitemallOrderGoods> collect = orderGoodsList.stream().filter(orderGoods -> orderGoods.getStockType() == 2).collect(Collectors.toList());
                Integer isHaveMedical = collect.size() > 0 ? 1 : 0;
                packageOrderListForm.setIsHasMedical(isHaveMedical);
                AgedmallLgBaseInfo baseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(packageOrderListBackDto.getId().longValue());
                List<Integer> orderGoodsIds = logisticBusiBaseServiceImpl.getorderGoodsIds(baseInfo.getLgContent());
                LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsIds.get(0));
                LitemallOrderItem orderItem = litemallOrderItemMapper.selectByPrimaryKey(orderGoods.getChildOrderId().intValue());
                if (isHospitalSelf(orderItem,orderGoods)) {
                    isSubHospital = 1;
                }
                //判断是否展示自提码
                if(orderGoods.getOrderGoodsStat().equals(LgBaseInfoStatConstant.PICK_UP_ALLOT_COMPLETE)&&orderGoods.getStockType()!=1&&orderGoods.getStockType()!=2){
                    String selfCode=stringRedisTemplate.opsForValue().get("self-"+baseInfo.getId().toString()+"-code");
                    if(StringUtils.isNotBlank(selfCode)){
                        packageOrderListForm.setExtractCode(Integer.parseInt(selfCode));
                    }
                }
            }
            //送货额外获取配送员信息
            if (type == 1) {
                AgedmallLgMission mission = agedmallLgMissionMapper.selectByPrimaryKey(packageOrderListBackDto.getMissionId());
                AgedmallLgReceiveOrder packageUserMessage = appOrderMapper.getPackageUserMessage(mission.getBaseInfoId());
                if (packageUserMessage != null) {
                    logger.debug("送货额外配送员信息不存在 {}", mission.getId());
                    PackerUserDto packerUserDto = new PackerUserDto(packageUserMessage);
                    packageOrderListForm.setPackerUser(packerUserDto);
                }
                if (mission.getMissionIsOver().equals(LgMissionIsOverEum.EXCEPTION.getCode())) {
                    packageOrderListForm.setErrorInfo(mission.getErrorReason());
                    packageOrderListForm.setErrorMark(mission.getErrorRemark());
                }
            }
            packageOrderListForm.setIsSubHospital(isSubHospital);
            rows.add(packageOrderListForm);
        }


        map.put("nowPage", packerOrderListVo.getPage());
        map.put("totalPage", page.getPages());
        map.put("totalRows", page.getTotal());
        map.put("rows", rows);
        return RespUtil.success(map);
    }


    public Object packerOrderAction(PackerOrderActionVo packerOrderActionVo, @LoginUser Integer userId) throws CheckException {
        String[] split = packerOrderActionVo.getPrinterCode().split("-");
        if (split.length < 2) {
            return RespUtil.fail(1011, "打印包裹码格式错误");
        }
        Integer missionId = Integer.parseInt(split[1]);
        Long recordId = appOrderMapper.getNowUserRecordOnce(userId, missionId);
        //检查订单
        boolean check = checkOrderState(recordId, missionId);
        if (!check) {
            logger.error("confirm接单检查错误：{}", recordId);
            return RespUtil.fail(500, "当前订单已被取消");
        }
        //TODO 拒接 后续再写
        if (packerOrderActionVo.getAction().equals("reject")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(0);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //TODO 接单 后续再写
        else if (packerOrderActionVo.getAction().equals("agree")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(1);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //完成配货
        else if (packerOrderActionVo.getAction().equals("finish")) {
            AgedmallLgMission lgMission = agedmallLgMissionMapper.selectByPrimaryKey(missionId);
            AgedmallLgBaseInfo baseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(lgMission.getBaseInfoId().longValue());
            List<Integer> orderGoodsIds = logisticBusiBaseServiceImpl.getorderGoodsIds(baseInfo.getLgContent());
            LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsIds.get(0));
            LitemallOrderItem orderItem = litemallOrderItemMapper.selectByPrimaryKey(orderGoods.getChildOrderId().intValue());
            if (isHospitalSelf(orderItem,orderGoods)) {
                String result = HttpRequest.post(serverAddress.getCenter() + "admin_api/getHpByMac/" + packerOrderActionVo.getHpMac())
                        //头信息，多个头信息多次调用此方法即可
                        .header(CenterServerAddress.KEY_HEADER_STRING, CenterServerAddress.KEY_SECUREUTIL_MD5)
                        .timeout(50000)//超时，毫秒
                        .execute().body();
                JSONObject jsonObject = JSON.parseObject(result);
                logger.debug("到桩自提获取到的hpId：{}", result);
                JSONObject dataObject = jsonObject.getJSONObject("data");
                Integer hpId = Integer.parseInt(dataObject.getString("id"));
                String position = dataObject.getString("position");
                inventoryService.refreshBindingEquAndHomePile(baseInfo.getStoreId());
                //获取当前桩绑定的equId
                Long orderGoodsRfid = Long.parseLong(orderGoods.getRfid());
                AgedmallGoodsEquExample goodsEquExample = new AgedmallGoodsEquExample();
                goodsEquExample.createCriteria().andTypeEqualTo(0).andHpIdEqualTo(hpId).andDeletedEqualTo((byte) 0)
                        .andEquIdEqualTo(orderGoodsRfid);
                AgedmallGoodsEqu goodsEqu = agedmallGoodsEquMapper.selectOneByExample(goodsEquExample);
                if (goodsEqu != null && goodsEqu.getEquId().equals(orderGoodsRfid)) {
                    logisticBusiBaseServiceImpl.deployOverEvent(missionId,
                            null, null,
                            packerOrderActionVo.getExpressCode(), packerOrderActionVo.getImages(), true);
                    //修改orderGoods
                    orderGoods.setHospitalSelfHpMac(packerOrderActionVo.getHpMac());
                    orderGoods.setHospitalSelfEquRfid(packerOrderActionVo.getEquRfid());
                    orderGoods.setHospitalSelfHpId(hpId);
                    orderGoods.setHospitalSelfPosition(position);
                    litemallOrderGoodsMapper.updateByPrimaryKeySelective(orderGoods);
                } else {
                    return RespUtil.fail(980, "请扫描插入指定轮椅的桩");
                }
            } else {
                List<ChainLockPickup> chainLockPickups = logisticBusiBaseServiceImpl.deployOverEvent(missionId,
                        null, null,
                        packerOrderActionVo.getExpressCode(), packerOrderActionVo.getImages(), false);
                //判断是否软链锁没有取出
                boolean isFinish = true;
                if (chainLockPickups != null && !chainLockPickups.isEmpty()) {
                    for (ChainLockPickup chain : chainLockPickups) {
                        if (chain.getPickUpStatus() == 0) {
                            isFinish = false;
                        }
                    }
                }
                if (!isFinish) {
                    return RespUtil.fail(980, "软链锁未取货");
                }
            }
        }

        return RespUtil.success();
    }


    public Object deliveryOrderAction(DeliveryOrderActionVo deliveryOrderActionVo, @LoginUser Integer userId) throws CheckException {
        String[] split = deliveryOrderActionVo.getPrinterCode().split("-");
        if (split.length < 2) {
            return RespUtil.fail(1011, "打印包裹码格式错误");
        }
        Integer missionId = Integer.parseInt(split[1]);
        Long recordId = appOrderMapper.getNowUserRecordOnce(userId, missionId);
        //检查订单
        boolean check = checkOrderState(recordId, missionId);
        if (!check) {
            logger.error("confirm接单检查错误：{}", recordId);
            return RespUtil.fail(500, "当前订单已被取消");
        }
        //TODO 拒接 后续再写
        if (deliveryOrderActionVo.getAction().equals("reject")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(0);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //TODO 接单 后续再写
        else if (deliveryOrderActionVo.getAction().equals("agree")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(1);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //开始送货
        else if (deliveryOrderActionVo.getAction().equals("begin")) {
            logisticBusiBaseServiceImpl.startReceiveOrderEvent(missionId);
        }
        //完成送货
        else if (deliveryOrderActionVo.getAction().equals("finish")) {
            logisticBusiBaseServiceImpl.deliveryOverEvent(missionId, null, deliveryOrderActionVo.getImages());
        }
        //异常操作
        else if (deliveryOrderActionVo.getAction().equals("exception")) {
            logisticBusiBaseServiceImpl.deployOverEventException(deliveryOrderActionVo.getImages(),
                    missionId, deliveryOrderActionVo.getErrorInfo(),
                    deliveryOrderActionVo.getErrorMark());
        }
        return RespUtil.success();
    }


    public Object lockSelfConfirm(Integer userId,  String hpMac, String equRfid,  String subOrderId) {
       return orderService.lockSelfConfirm(userId, equRfid, subOrderId);
    }

    public Object pickupOrderAction(DeliveryOrderActionVo deliveryOrderActionVo, @LoginUser Integer userId) throws CheckException {
        String[] split = deliveryOrderActionVo.getPrinterCode().split("-");
        if (split.length < 2) {
            return RespUtil.fail(1011, "打印包裹码格式错误");
        }
        Integer missionId = Integer.parseInt(split[1]);
        Long recordId = appOrderMapper.getNowUserRecordOnce(userId, missionId);
        //检查订单
        boolean check = checkOrderState(recordId, missionId);
        if (!check) {
            logger.error("confirm接单检查错误：{}", recordId);
            return RespUtil.fail(500, "当前订单已被取消");
        }
        //判断订单状态是否已取消
        //TODO 拒接 后续再写
        if (deliveryOrderActionVo.getAction().equals("reject")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(0);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //TODO 接单 后续再写
        else if (deliveryOrderActionVo.getAction().equals("agree")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(1);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //开始取货
        else if (deliveryOrderActionVo.getAction().equals("begin")) {
            logisticBusiBaseServiceImpl.startReceiveOrderEvent(missionId);
        }
        //检测设备
        else if (deliveryOrderActionVo.getAction().equals("check")) {
            Map<String, Object> map = new HashMap<>();
            Integer isHome = 1;
            AgedmallLgMission lgMission = agedmallLgMissionMapper.selectByPrimaryKey(missionId);
            AgedmallLgBaseInfo agedmallLgBaseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(lgMission.getBaseInfoId().longValue());

            String bigOrderCode = agedmallLgBaseInfo.getOrderCode();
            logisticBusiBaseServiceImpl.checkLgBaseOrderStat(bigOrderCode);

//            List<ChainLockPickup> chainLockPickups = logisticBusiBaseServiceImpl.checkChainIsFinish(agedmallLgBaseInfo.getLgContent());
//            //判断是否有软链，如果有，是否已经全部归还
//            if (!chainLockPickups.isEmpty()) {
//                for (ChainLockPickup chain : chainLockPickups) {
//                    if (chain.getPickUpStatus() != 2) {
//                        isHome = 0;
//                        map.put("isHoming", isHome);
//                        return RespUtil.success(map);
//                    }
//                }
//            }
            List<MedicalLockPickup> medicalLockPickups = logisticBusiBaseServiceImpl.checkCabinetIsFinish(agedmallLgBaseInfo.getLgContent());
            //判断是否有医柜锁，如果有，是否已经全部归还
            if (!medicalLockPickups.isEmpty()) {
                for (MedicalLockPickup cabinet : medicalLockPickups) {
                    if (cabinet.getState() != 2) {
                        isHome = 0;
                        map.put("isHoming", isHome);
                        return RespUtil.success(map);
                    }
                }
            }
            map.put("isHoming", isHome);
            return RespUtil.success(map);
        }
        //完成取回
        else if (deliveryOrderActionVo.getAction().equals("finish")) {

            AgedmallLgMission lgMission = agedmallLgMissionMapper.selectByPrimaryKey(missionId);
            AgedmallLgBaseInfo agedmallLgBaseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(lgMission.getBaseInfoId().longValue());

            String bigOrderCode = agedmallLgBaseInfo.getOrderCode();
            logisticBusiBaseServiceImpl.checkLgBaseOrderStat(bigOrderCode);

            //如果是归还调用方法
            if (agedmallLgBaseInfo.getLgType().equals(LgBaseInfoLgType.GIVEBACK.getCode())) {
                boolean isFinish = logisticBusiBaseServiceImpl.returnCompleteEvent(missionId, null, deliveryOrderActionVo.getImages());
                if (!isFinish) {
                    return RespUtil.fail(600, "归还失败");
                }
                //获取子订单单号
                List<Integer> orderGoodsIds = logisticBusiBaseServiceImpl.getorderGoodsIds(agedmallLgBaseInfo.getLgContent());
                LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsIds.get(0));
                LitemallOrderItem subOrder = litemallOrderService.findItemById(orderGoods.getChildOrderId().intValue());
                //计算价格
                leaseOrderService.orderSettlement(agedmallLgBaseInfo.getOrderCode(), subOrder.getChildOrderCode());


            }
            //换货-退货-取回  后台管理使用
            else if (agedmallLgBaseInfo.getLgType().equals(LgBaseInfoLgType.EXCHANGE.getCode())) {
                logisticBusiBaseServiceImpl.exchangeAcquisitionCompletionEvent(missionId, deliveryOrderActionVo.getImages());
            }
            //退货   后台管理使用
            else if (agedmallLgBaseInfo.getLgType().equals(LgBaseInfoLgType.RETURNTHEGOODS.getCode())) {
                //退货完成
                logisticBusiBaseServiceImpl.rejectedGoodsEvent(missionId, deliveryOrderActionVo.getImages());
                //获取子订单单号
                List<Integer> orderGoodsIds = logisticBusiBaseServiceImpl.getorderGoodsIds(agedmallLgBaseInfo.getLgContent());
                LitemallOrderGoods orderGoods = litemallOrderGoodsMapper.selectByPrimaryKey(orderGoodsIds.get(0));
                LitemallOrderItem subOrder = litemallOrderService.findItemById(orderGoods.getChildOrderId().intValue());
                //售卖订单 退货完成后 才会退款
                leaseOrderService.orderSettlementRefund(agedmallLgBaseInfo.getOrderCode(), subOrder.getChildOrderCode());
            }

        }
        return RespUtil.success();
    }


    public Object repairOrderAction(DeliveryOrderActionVo deliveryOrderActionVo, @LoginUser Integer userId) throws CheckException {
        String[] split = deliveryOrderActionVo.getPrinterCode().split("-");
        if (split.length < 2) {
            return RespUtil.fail(1011, "打印包裹码格式错误");
        }
        Integer missionId = Integer.parseInt(split[1]);
        Long recordId = appOrderMapper.getNowUserRecordOnce(userId, missionId);
        //TODO 拒接 后续再写
        if (deliveryOrderActionVo.getAction().equals("reject")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(0);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //TODO 接单 后续再写
        else if (deliveryOrderActionVo.getAction().equals("agree")) {
            ToLitemallBean toLitemallBean = new ToLitemallBean();
            toLitemallBean.setId(recordId);
            toLitemallBean.setType(1);
            directExchangeProducer.send(JSONUtil.toJsonStr(toLitemallBean), DirectExchangeRabbitMQConfig.TO_LITEMALL);
        }
        //开始维护
        else if (deliveryOrderActionVo.getAction().equals("begin")) {
            logisticBusiBaseServiceImpl.startReceiveOrderEvent(Integer.parseInt(split[1]));
        }
        //检测设备
        else if (deliveryOrderActionVo.getAction().equals("check")) {
            Map<String, Object> map = new HashMap<>();
            Integer isHome = 1;
            AgedmallLgMission lgMission = agedmallLgMissionMapper.selectByPrimaryKey(missionId);
            AgedmallLgBaseInfo agedmallLgBaseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(lgMission.getBaseInfoId().longValue());
            List<ChainLockPickup> chainLockPickups = logisticBusiBaseServiceImpl.checkChainIsFinish(agedmallLgBaseInfo.getLgContent());
            //判断是否有软链，如果有，是否已经全部归还
            if (!chainLockPickups.isEmpty()) {
                for (ChainLockPickup chain : chainLockPickups) {
//                    if (chain.getPickUpStatus() != 3) {
//                        isHome = 0;
//                        map.put("isHoming", isHome);
//                        return RespUtil.success(map);
//                    }
                    //TODO 软链锁暂时不做处理

                }
            }
            List<MedicalLockPickup> medicalLockPickups = logisticBusiBaseServiceImpl.checkCabinetIsFinish(agedmallLgBaseInfo.getLgContent());
            //判断是否有医柜锁，如果有，是否已经全部归还
            if (!medicalLockPickups.isEmpty()) {
                for (MedicalLockPickup cabinet : medicalLockPickups) {
                    if (cabinet.getState() != 2) {
                        isHome = 0;
                        map.put("isHoming", isHome);
                        return RespUtil.success(map);
                    }
                }
            }
            map.put("isHoming", isHome);
            return RespUtil.success(map);
        }
        //完成维护
        else if (deliveryOrderActionVo.getAction().equals("finish")) {
            logisticBusiBaseServiceImpl.maintenanceCompletionEvent(missionId, null, deliveryOrderActionVo.getImages());
        }
        return RespUtil.success();
    }


    public Object selfConfirm(SelfConfirmVo selfConfirmVo, Integer userId) {
        return orderService.selfConfirm(selfConfirmVo, userId);
    }


    public boolean checkOrderState(Long recordId, Integer missionId) {
        AgedmallLgMission mission = agedmallLgMissionMapper.selectByPrimaryKey(missionId);
        AgedmallLgBaseInfo lgBaseInfo = agedmallLgBaseInfoMapper.selectByPrimaryKey(mission.getBaseInfoId().longValue());
        //检查订单是否可以继续
        try {
            logisticBusiBaseServiceImpl.checkLgBaseOrderStat(lgBaseInfo.getOrderCode());
            if (lgBaseInfo.getLgType().equals(LgBaseInfoLgType.GIVEBACK.getCode())) {
                logisticBusiBaseServiceImpl.checkBackIsCancel(lgBaseInfo.getLgIsOver());
            }

        } catch (CheckException e) {
            logger.error("当前订单/归还已被取消：{}", lgBaseInfo.getId());
            if (recordId != null) {
                String redisKey = WechatConstant.TEMPLATE_RESPONSE_CODE_REDIS_KEY + recordId.toString();
                String code = stringRedisTemplate.opsForValue().get(redisKey);
                if (StrUtil.isNotBlank(code)) {
                    //控制模板变为不可用
                    ReceivedBean receivedBean = new ReceivedBean();
                    receivedBean.setType(1);
                    receivedBean.setResponseCode(code);
                    receivedBean.setButtonMsg("已取消");
                    directExchangeProducer.send(JSONUtil.toJsonStr(receivedBean), DirectExchangeRabbitMQConfig.TO_WECHAT_NOTICE);
                    stringRedisTemplate.delete(redisKey);
                }
            }
            return false;
        }

        return true;
    }


    public BaseResult getExtractInfo(Integer userId,ExtractInfoVo extractInfoVo){
        Map<String,Object> map =new HashMap<>();
        String returnType="";

        LitemallOrderItem orderItem=null;
        List<LitemallOrderGoods> orderGoodsList=new ArrayList<>();

        AgedmallDeliveryManInfo deliveryManIsInStore = null;

        LitemallOrderGoods hasMaintenanceOrder = null;

        if(extractInfoVo.getType().equals("order")){
            LitemallOrderItemExample itemExample=new LitemallOrderItemExample();
            itemExample.createCriteria().andChildOrderCodeEqualTo(extractInfoVo.getData());
             orderItem = litemallOrderItemMapper.selectOneByExample(itemExample);
            LitemallOrderGoodsExample orderGoodsExample=new LitemallOrderGoodsExample();
            orderGoodsExample.createCriteria().andChildOrderIdEqualTo(orderItem.getId().longValue());
            orderGoodsList = litemallOrderGoodsMapper.selectByExample(orderGoodsExample);
            deliveryManIsInStore = appHospitalMapper.getDeliveryManIsInStore(userId,orderItem.getStoreId());
            hasMaintenanceOrder = appHospitalMapper.getMaintenanceByEquId(orderGoodsList.get(0).getRfid());
        }
        else{
            String result = HttpRequest.post(serverAddress.getCenter() + "admin_api/getHpByQrc/" + extractInfoVo.getData())
                    //头信息，多个头信息多次调用此方法即可
                    .header(CenterServerAddress.KEY_HEADER_STRING, CenterServerAddress.KEY_SECUREUTIL_MD5)
                    .timeout(50000)//超时，毫秒
                    .execute().body();
            JSONObject jsonObject = JSON.parseObject(result);
            logger.debug("根据qrc获取的equId：{}", result);
            String equId = jsonObject.get("data").toString();
            LitemallOrderGoodsExample orderGoodsExample=new LitemallOrderGoodsExample();
            orderGoodsExample.createCriteria().andStockTypeEqualTo(1).andRfidEqualTo(equId)
                    .andOrderGoodsStatLessThan(LgBaseInfoStatConstant.LEASE_BACK);
            orderGoodsList = litemallOrderGoodsMapper.selectByExample(orderGoodsExample);

            if(orderGoodsList.size()>0){
                orderItem = litemallOrderItemMapper.selectByPrimaryKey(orderGoodsList.get(0).getChildOrderId().intValue());
                deliveryManIsInStore = appHospitalMapper.getDeliveryManIsInStore(userId, orderItem.getStoreId());
                if(orderItem.getExtractShop() == null){
                    orderItem=null;
                    orderGoodsList=new ArrayList<>();
                }
            }
            hasMaintenanceOrder = appHospitalMapper.getMaintenanceByEquId(equId);
        }
        //如果子订单和维护订单都不存在并且用户不是兼职人员
        if(orderGoodsList.size()==0&&ObjectUtil.isNull(hasMaintenanceOrder)&&ObjectUtil.isNull(deliveryManIsInStore)){
            returnType="notOrder";
            map.put("type",returnType);
            return RespUtil.success(map);
        }
        //如果子订单和维护订单都不存在并且用户是兼职人员
        else if(orderGoodsList.size()==0&&ObjectUtil.isNull(hasMaintenanceOrder)&&ObjectUtil.isNotNull(deliveryManIsInStore)){
            returnType="notAccess";
            map.put("type",returnType);
            return RespUtil.success(map);
        }
        //如果子订单存在 并且是当前用户下的单
        else if(orderGoodsList.size()>0&&orderItem.getUserId().equals(userId)){
            StoreGoodsVo info = agedmallStoreGoodsService.getStoreGoodsById(orderGoodsList.get(0).getStoreGoodsId());

            //到店 自提
            if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_SELF)) {
                map=assambleStoreSelfMap(info,orderGoodsList,orderItem);

                return RespUtil.success(map);
            }
            //到院自提
            else if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
                HospitalBase hospitalBase=new HospitalBase();

                JSONObject jsonObject = JSON.parseObject(orderItem.getDeliveryChoose());
                String type = (String) jsonObject.get("type");
                if (type.equals("subHospitalSelf")) {
                    hospitalBase.setOrderInfo(assambleOrderInfo(info,orderGoodsList,orderItem));
                    hospitalBase.setExtractInfo(assambleExtractInfo(orderItem));
                    hospitalBase.setDeviceInfo(assambleDeviceInfo(orderGoodsList.get(0)));
                    hospitalBase.setPositionInfo(assamblePositaionInfo(orderGoodsList.get(0)));
                    hospitalBase.setHospitalInfo(assambleHospitalInfo(orderItem,orderGoodsList.get(0)));
                    if(orderGoodsList.get(0).getHospitalSelfLocationId()!=null&&orderGoodsList.get(0).getLocationHpType()==0){
                      returnType="hospitalBase";
                      map.put("type",returnType);
                      map.put("hospitalBase",hospitalBase);
                    }
                    else{
                        returnType="hospitalLock";
                        map.put("type",returnType);
                        map.put("hospitalLock",hospitalBase);
                    }

                    return RespUtil.success(map);
                }
                if (type.equals("subStoreSelf")) {
                    map=assambleStoreSelfMap(info,orderGoodsList,orderItem);
                    return RespUtil.success(map);
                }
            }




            map.put("type",returnType);
            return RespUtil.success(map);
        }
        //如果子订单不存在 维护单存在
        //如果 子订单存在并且当前用户不是下单用户 并且当前用户是兼职人员
        else if((orderGoodsList.size()==0&&ObjectUtil.isNotNull(hasMaintenanceOrder))||
                (orderGoodsList.size()>0&&!orderItem.getUserId().equals(userId)&&ObjectUtil.isNotNull(deliveryManIsInStore))){
            returnType="hasAccess";
            map.put("type",returnType);
            StoreGoodsVo info = agedmallStoreGoodsService.getStoreGoodsById(orderGoodsList.get(0).getStoreGoodsId());
            HasAccess hasAccess=new HasAccess();
            hasAccess.setOrderInfo(assambleOrderInfo(info,orderGoodsList,orderItem));
            hasAccess.setDeviceInfo(assambleDeviceInfo(orderGoodsList.get(0)));
            map.put("hasAccess",hasAccess);
            return RespUtil.success(map);
        }


        return RespUtil.success(map);
    }


    public OrderInfo assambleOrderInfo(StoreGoodsVo info,List<LitemallOrderGoods> orderGoodsList,LitemallOrderItem orderItem){
        OrderInfo orderInfo=new OrderInfo();
        List<HospitalGoodsBaseData> goodsList=new ArrayList<>();
        HospitalGoodsBaseData hospitalGoodsBaseData=new HospitalGoodsBaseData();
        hospitalGoodsBaseData.setId(info.getId());
        hospitalGoodsBaseData.setName(info.getName());
        hospitalGoodsBaseData.setImage(info.getPicUrl());
        hospitalGoodsBaseData.setBuycount(orderGoodsList.get(0).getNumber().intValue());
        hospitalGoodsBaseData.setType(info.getGoodsType());
        hospitalGoodsBaseData.setPrice(orderGoodsList.get(0).getPrice());
        hospitalGoodsBaseData.setSkuName(getSkuName(orderGoodsList.get(0).getSpecifications()));
        LitemallGoodsProduct goodsProduct=litemallGoodsProductMapper.selectByPrimaryKey(orderGoodsList.get(0).getProductId());
        GoodsVipSalesDto selectProductVipSale = cartManager.getSelectProductVipSale(goodsProduct.getVipJson(),orderItem.getUserId(),
                orderGoodsList.get(0).getNumber().intValue(),info.getVipPriceFlag());
        hospitalGoodsBaseData.setSelectedSkuVipSale(selectProductVipSale);
        orderInfo.setBigOrderId(orderItem.getOrderCode());
        orderInfo.setSubOrderId(orderItem.getChildOrderCode());
        goodsList.add(hospitalGoodsBaseData);
        orderInfo.setGoodsList(goodsList);
        return orderInfo;
    }


    public ExtractInfo assambleExtractInfo(LitemallOrderItem orderItem){

            ExtractInfo extractInfo = new ExtractInfo();
            String dateTimeString = "请在  内自提，否则订单将取消";
            String dateFormat = "";
            LocalDateTime subTime = LocalDateTime.now();
            String cancelRuleName = "自提取消规则";
            //默认为24小时候
            //type 0-门店自提 1-医院自提
            extractInfo.setType(0);
            if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_SELF)) {
                subTime = orderItem.getAddTime();
            } else if (orderItem.getDeliverySn().equals(AgedmallShipDictConstant.SHIP_SN_HOSPITAL)) {
                JSONObject jsonObject = JSON.parseObject(orderItem.getDeliveryChoose());
                String type = (String) jsonObject.get("type");
                if (type.equals("subHospitalSelf")) {
                    extractInfo.setType(1);
                }
                if (type.equals("subStoreSelf") || type.equals("subHospitalSelf")) {
                    JSONObject hosJSON = JSON.parseObject(orderItem.getDeliveryChoose());
                    String date = (String) hosJSON.get("date") + " " + (String) hosJSON.get("endTime") + ":00";
                    subTime = cn.hutool.core.date.DateUtil.parseLocalDateTime(date);
                    cancelRuleName = "预约自提规则";
                }
            } else {
                subTime = orderItem.getAddTime();
            }
            DateTime dateTime = cn.hutool.core.date.DateUtil.offsetDay(Date.from(subTime.atZone(ZoneId.systemDefault()).toInstant()), 1);
            dateFormat = cn.hutool.core.date.DateUtil.formatDateTime(dateTime);
            dateTimeString = "请在 " + dateFormat + " 内自提，否则订单将取消";
            extractInfo.setDatetime(dateFormat);
            extractInfo.setNotice(dateTimeString);
            extractInfo.setCancelRuleName(cancelRuleName);
            extractInfo.setCancelRuleDesc("");



        return extractInfo;
    }


    public StoreInfo assambleStoreInfo(LitemallOrderItem orderItem){
        AgedmallStore store=agedmallStoreMapper.selectByPrimaryKey(orderItem.getStoreId().longValue());
        return new StoreInfo(store);
    }

    public PositionInfo assamblePositaionInfo(LitemallOrderGoods orderGoods){
        PositionInfo positionInfo=new PositionInfo();
        if(orderGoods.getHospitalSelfLocationId()!=null&&orderGoods.getLocationHpType()==0){
            AgedmallHospitalSendSelfLocation selfLocation=agedmallHospitalSendSelfLocationMapper.selectByPrimaryKey(orderGoods.getHospitalSelfLocationId());
            positionInfo.setName(selfLocation.getSelfLocationName());
            positionInfo.setPosition(selfLocation.getLocationRemark());
            positionInfo.setImage(selfLocation.getLocationImgs());
        }
        else{
            positionInfo.setPosition(orderGoods.getHospitalSelfPosition());
        }

        return positionInfo;
    }



    public DeviceInfo assambleDeviceInfo(LitemallOrderGoods orderGoods){
        DeviceInfo deviceInfo=new DeviceInfo();
        deviceInfo.setHpMac(orderGoods.getHospitalSelfHpMac());
        deviceInfo.setEquRfid(orderGoods.getHospitalSelfEquRfid());
        deviceInfo.setEquId(orderGoods.getRfid());
        deviceInfo.setHpId(orderGoods.getHospitalSelfHpId() != null ? orderGoods.getHospitalSelfHpId().toString() : null);
        return  deviceInfo;
    }

    public Map<String,Object> assambleStoreSelfMap(StoreGoodsVo info,List<LitemallOrderGoods> orderGoodsList,LitemallOrderItem orderItem){
        Map<String,Object> map = new HashMap<>();
        String returnType="";
        StoreBase storeBase=new StoreBase();
        storeBase.setOrderInfo(assambleOrderInfo(info,orderGoodsList,orderItem));
        storeBase.setExtractInfo(assambleExtractInfo(orderItem));
        storeBase.setStoreInfo(assambleStoreInfo(orderItem));
        storeBase.setPositionInfo(assamblePositaionInfo(orderGoodsList.get(0)));
        //软链锁
        if(orderGoodsList.get(0).getStockType()==1){
            returnType="storeLock";
            storeBase.setDeviceInfo(assambleDeviceInfo(orderGoodsList.get(0)));
            map.put("storeLock",storeBase);
        }
        //无软链锁
        else{
            returnType="storeBase";
            map.put("storeBase",storeBase);
        }
        map.put("type",returnType);
        return map;
    }

    public HospitalInfo assambleHospitalInfo(LitemallOrderItem item,LitemallOrderGoods orderGoods){
        AgedmallHospitalSend hospitalSend=agedmallHospitalSendService.getById(item.getHospitalId());
        HospitalInfo hospitalInfo=new HospitalInfo(hospitalSend);
        if(orderGoods.getHospitalSelfLocationId()!=null&&orderGoods.getLocationHpType()==0){
            AgedmallHospitalSendSelfLocation selfLocation=agedmallHospitalSendSelfLocationMapper.selectByPrimaryKey(orderGoods.getHospitalSelfLocationId());
            String[] phoneArray=selfLocation.getAdminPhone().split(",");
            hospitalInfo.setPhone(phoneArray[0]);
        }
        return hospitalInfo;
    }

    public String getSkuName(String spec){
            List<LitemallGoodsProductSpecification> specifications
                    = JSON.parseArray(spec, LitemallGoodsProductSpecification.class);
            StringBuffer sku = new StringBuffer();
            for (LitemallGoodsProductSpecification lgs : specifications) {
                StringBuffer sb = new StringBuffer();
                sb.append(lgs.getInfoName()).append(":").append(lgs.getName());
                sku.append(sb).append(";");
            }

            String spiltSku = sku.substring(0, sku.length() - 1);
           return spiltSku;
    }

}
